| Index: src/debug.cc
 | 
| diff --git a/src/debug.cc b/src/debug.cc
 | 
| index c70b834f7abdebb75f34a8fcd695607732f89e51..4ebdd88730d77f914cfbd2e3f313cc079d19db7b 100644
 | 
| --- a/src/debug.cc
 | 
| +++ b/src/debug.cc
 | 
| @@ -698,7 +698,7 @@ void Debug::HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data) {
 | 
|    // We need to clear all breakpoints associated with the function to restore
 | 
|    // original code and avoid patching the code twice later because
 | 
|    // the function will live in the heap until next gc, and can be found by
 | 
| -  // Runtime::FindSharedFunctionInfoInScript.
 | 
| +  // Debug::FindSharedFunctionInfoInScript.
 | 
|    BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
 | 
|    it.ClearAllDebugBreak();
 | 
|    debug->RemoveDebugInfo(node->debug_info());
 | 
| @@ -1172,11 +1172,10 @@ bool Debug::SetBreakPointForScript(Handle<Script> script,
 | 
|                                     int* source_position) {
 | 
|    HandleScope scope(isolate_);
 | 
|  
 | 
| -  // No need to call PrepareForBreakPoints because it will be called
 | 
| -  // implicitly by Runtime::FindSharedFunctionInfoInScript.
 | 
| -  Object* result = Runtime::FindSharedFunctionInfoInScript(isolate_,
 | 
| -                                                           script,
 | 
| -                                                           *source_position);
 | 
| +  PrepareForBreakPoints();
 | 
| +
 | 
| +  // Obtain shared function info for the function.
 | 
| +  Object* result = FindSharedFunctionInfoInScript(script, *source_position);
 | 
|    if (result->IsUndefined()) return false;
 | 
|  
 | 
|    // Make sure the function has set up the debug info.
 | 
| @@ -2092,6 +2091,115 @@ void Debug::PrepareForBreakPoints() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +Object* Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
 | 
| +                                              int position) {
 | 
| +  // Iterate the heap looking for SharedFunctionInfo generated from the
 | 
| +  // script. The inner most SharedFunctionInfo containing the source position
 | 
| +  // for the requested break point is found.
 | 
| +  // NOTE: This might require several heap iterations. If the SharedFunctionInfo
 | 
| +  // which is found is not compiled it is compiled and the heap is iterated
 | 
| +  // again as the compilation might create inner functions from the newly
 | 
| +  // compiled function and the actual requested break point might be in one of
 | 
| +  // these functions.
 | 
| +  // NOTE: The below fix-point iteration depends on all functions that cannot be
 | 
| +  // compiled lazily without a context to not be compiled at all. Compilation
 | 
| +  // will be triggered at points where we do not need a context.
 | 
| +  bool done = false;
 | 
| +  // The current candidate for the source position:
 | 
| +  int target_start_position = RelocInfo::kNoPosition;
 | 
| +  Handle<JSFunction> target_function;
 | 
| +  Handle<SharedFunctionInfo> target;
 | 
| +  while (!done) {
 | 
| +    { // Extra scope for iterator and no-allocation.
 | 
| +      isolate_->heap()->EnsureHeapIsIterable();
 | 
| +      AssertNoAllocation no_alloc_during_heap_iteration;
 | 
| +      HeapIterator iterator;
 | 
| +      for (HeapObject* obj = iterator.next();
 | 
| +           obj != NULL; obj = iterator.next()) {
 | 
| +        bool found_next_candidate = false;
 | 
| +        Handle<JSFunction> function;
 | 
| +        Handle<SharedFunctionInfo> shared;
 | 
| +        if (obj->IsJSFunction()) {
 | 
| +          function = Handle<JSFunction>(JSFunction::cast(obj));
 | 
| +          shared = Handle<SharedFunctionInfo>(function->shared());
 | 
| +          ASSERT(shared->allows_lazy_compilation() || shared->is_compiled());
 | 
| +          found_next_candidate = true;
 | 
| +        } else if (obj->IsSharedFunctionInfo()) {
 | 
| +          shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj));
 | 
| +          // Skip functions that we cannot compile lazily without a context,
 | 
| +          // which is not available here, because there is no closure.
 | 
| +          found_next_candidate = shared->is_compiled() ||
 | 
| +              shared->allows_lazy_compilation_without_context();
 | 
| +        }
 | 
| +        if (!found_next_candidate) continue;
 | 
| +        if (shared->script() == *script) {
 | 
| +          // If the SharedFunctionInfo found has the requested script data and
 | 
| +          // contains the source position it is a candidate.
 | 
| +          int start_position = shared->function_token_position();
 | 
| +          if (start_position == RelocInfo::kNoPosition) {
 | 
| +            start_position = shared->start_position();
 | 
| +          }
 | 
| +          if (start_position <= position &&
 | 
| +              position <= shared->end_position()) {
 | 
| +            // If there is no candidate or this function is within the current
 | 
| +            // candidate this is the new candidate.
 | 
| +            if (target.is_null()) {
 | 
| +              target_start_position = start_position;
 | 
| +              target_function = function;
 | 
| +              target = shared;
 | 
| +            } else {
 | 
| +              if (target_start_position == start_position &&
 | 
| +                  shared->end_position() == target->end_position()) {
 | 
| +                // If a top-level function contains only one function
 | 
| +                // declaration the source for the top-level and the function
 | 
| +                // is the same. In that case prefer the non top-level function.
 | 
| +                if (!shared->is_toplevel()) {
 | 
| +                  target_start_position = start_position;
 | 
| +                  target_function = function;
 | 
| +                  target = shared;
 | 
| +                }
 | 
| +              } else if (target_start_position <= start_position &&
 | 
| +                         shared->end_position() <= target->end_position()) {
 | 
| +                // This containment check includes equality as a function
 | 
| +                // inside a top-level function can share either start or end
 | 
| +                // position with the top-level function.
 | 
| +                target_start_position = start_position;
 | 
| +                target_function = function;
 | 
| +                target = shared;
 | 
| +              }
 | 
| +            }
 | 
| +          }
 | 
| +        }
 | 
| +      }  // End for loop.
 | 
| +    }  // End no-allocation scope.
 | 
| +
 | 
| +    if (target.is_null()) {
 | 
| +      return isolate_->heap()->undefined_value();
 | 
| +    }
 | 
| +
 | 
| +    // There will be at least one break point when we are done.
 | 
| +    has_break_points_ = true;
 | 
| +
 | 
| +    // If the candidate found is compiled we are done.
 | 
| +    done = target->is_compiled();
 | 
| +    if (!done) {
 | 
| +      // If the candidate is not compiled, compile it to reveal any inner
 | 
| +      // functions which might contain the requested source position. This
 | 
| +      // will compile all inner functions that cannot be compiled without a
 | 
| +      // context, because Compiler::BuildFunctionInfo checks whether the
 | 
| +      // debugger is active.
 | 
| +      if (target_function.is_null()) {
 | 
| +        SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION);
 | 
| +      } else {
 | 
| +        JSFunction::CompileLazy(target_function, KEEP_EXCEPTION);
 | 
| +      }
 | 
| +    }
 | 
| +  }  // End while loop.
 | 
| +
 | 
| +  return *target;
 | 
| +}
 | 
| +
 | 
| +
 | 
|  // Ensures the debug information is present for shared.
 | 
|  bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
 | 
|                              Handle<JSFunction> function) {
 | 
| 
 |