| Index: src/runtime.cc | 
| diff --git a/src/runtime.cc b/src/runtime.cc | 
| index 9e389492eca14cf87aec73a292b6a4794bd21e3e..e72d9a20eb910fd7ee2a8dab351f80ae2598591e 100644 | 
| --- a/src/runtime.cc | 
| +++ b/src/runtime.cc | 
| @@ -2183,8 +2183,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) { | 
| Handle<SharedFunctionInfo> target_shared(target->shared()); | 
| Handle<SharedFunctionInfo> source_shared(source->shared()); | 
|  | 
| -  if (!source->is_compiled() && | 
| -      !JSFunction::CompileLazy(source, KEEP_EXCEPTION)) { | 
| +  if (!JSFunction::EnsureCompiled(source, KEEP_EXCEPTION)) { | 
| return Failure::Exception(); | 
| } | 
|  | 
| @@ -4855,14 +4854,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugCallbackSupportsStepping) { | 
| RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) { | 
| Debug* debug = isolate->debug(); | 
| if (!debug->IsStepping()) return NULL; | 
| -  CONVERT_ARG_CHECKED(Object, callback, 0); | 
| +  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0); | 
| HandleScope scope(isolate); | 
| -  Handle<SharedFunctionInfo> shared_info(JSFunction::cast(callback)->shared()); | 
| // When leaving the callback, step out has been activated, but not performed | 
| // if we do not leave the builtin.  To be able to step into the callback | 
| // again, we need to clear the step out at this point. | 
| debug->ClearStepOut(); | 
| -  debug->FloodWithOneShot(shared_info); | 
| +  debug->FloodWithOneShot(callback); | 
| return NULL; | 
| } | 
|  | 
| @@ -8140,12 +8138,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) { | 
| } | 
|  | 
| // The function should be compiled for the optimization hints to be | 
| -  // available. We cannot use EnsureCompiled because that forces a | 
| -  // compilation through the shared function info which makes it | 
| -  // impossible for us to optimize. | 
| -  if (!function->is_compiled()) { | 
| -    JSFunction::CompileLazy(function, CLEAR_EXCEPTION); | 
| -  } | 
| +  // available. | 
| +  JSFunction::EnsureCompiled(function, CLEAR_EXCEPTION); | 
|  | 
| Handle<SharedFunctionInfo> shared(function->shared(), isolate); | 
| if (!function->has_initial_map() && | 
| @@ -11155,7 +11149,7 @@ class ScopeIterator { | 
| } | 
|  | 
| // Get the debug info (create it if it does not exist). | 
| -    if (!isolate->debug()->EnsureDebugInfo(shared_info)) { | 
| +    if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) { | 
| // Return if ensuring debug info failed. | 
| return; | 
| } | 
| @@ -11678,30 +11672,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetBreakLocations) { | 
| } | 
|  | 
|  | 
| -// Set a break point in a function | 
| -// args[0]: function | 
| -// args[1]: number: break source position (within the function source) | 
| -// args[2]: number: break point object | 
| -RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) { | 
| -  HandleScope scope(isolate); | 
| -  ASSERT(args.length() == 3); | 
| -  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); | 
| -  Handle<SharedFunctionInfo> shared(fun->shared()); | 
| -  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 
| -  RUNTIME_ASSERT(source_position >= 0); | 
| -  Handle<Object> break_point_object_arg = args.at<Object>(2); | 
| - | 
| -  // Set break point. | 
| -  isolate->debug()->SetBreakPoint(shared, break_point_object_arg, | 
| -                                  &source_position); | 
| - | 
| -  return Smi::FromInt(source_position); | 
| -} | 
| - | 
| - | 
| Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate, | 
| Handle<Script> script, | 
| int position) { | 
| +  // 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. | 
| +  isolate->debug()->PrepareForBreakPoints(); | 
| + | 
| // 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. | 
| @@ -11713,6 +11691,7 @@ Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate, | 
| 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. | 
| @@ -11721,60 +11700,80 @@ Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate, | 
| HeapIterator iterator; | 
| for (HeapObject* obj = iterator.next(); | 
| obj != NULL; obj = iterator.next()) { | 
| -        if (obj->IsSharedFunctionInfo()) { | 
| -          Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj)); | 
| -          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 = shared; | 
| -              } else { | 
| -                if (target_start_position == start_position && | 
| -                    shared->end_position() == target->end_position()) { | 
| -                    // If a top-level function contain only one function | 
| -                    // declartion 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 = 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. | 
| +        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. | 
| +    }  // End no-allocation scope. | 
|  | 
| if (target.is_null()) { | 
| return isolate->heap()->undefined_value(); | 
| } | 
|  | 
| -    // If the candidate found is compiled we are done. NOTE: when lazy | 
| -    // compilation of inner functions is introduced some additional checking | 
| -    // needs to be done here to compile inner functions. | 
| +    // 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. | 
| -      SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION); | 
| +      // 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. | 
|  | 
| @@ -11782,6 +11781,26 @@ Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate, | 
| } | 
|  | 
|  | 
| +// Set a break point in a function. | 
| +// args[0]: function | 
| +// args[1]: number: break source position (within the function source) | 
| +// args[2]: number: break point object | 
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) { | 
| +  HandleScope scope(isolate); | 
| +  ASSERT(args.length() == 3); | 
| +  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | 
| +  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 
| +  RUNTIME_ASSERT(source_position >= 0); | 
| +  Handle<Object> break_point_object_arg = args.at<Object>(2); | 
| + | 
| +  // Set break point. | 
| +  isolate->debug()->SetBreakPoint(function, break_point_object_arg, | 
| +                                  &source_position); | 
| + | 
| +  return Smi::FromInt(source_position); | 
| +} | 
| + | 
| + | 
| // Changes the state of a break point in a script and returns source position | 
| // where break point was set. NOTE: Regarding performance see the NOTE for | 
| // GetScriptFromScriptData. | 
| @@ -11800,23 +11819,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) { | 
| RUNTIME_ASSERT(wrapper->value()->IsScript()); | 
| Handle<Script> script(Script::cast(wrapper->value())); | 
|  | 
| -  Object* result = Runtime::FindSharedFunctionInfoInScript( | 
| -      isolate, script, source_position); | 
| -  if (!result->IsUndefined()) { | 
| -    Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); | 
| -    // Find position within function. The script position might be before the | 
| -    // source position of the first function. | 
| -    int position; | 
| -    if (shared->start_position() > source_position) { | 
| -      position = 0; | 
| -    } else { | 
| -      position = source_position - shared->start_position(); | 
| -    } | 
| -    isolate->debug()->SetBreakPoint(shared, break_point_object_arg, &position); | 
| -    position += shared->start_position(); | 
| -    return Smi::FromInt(position); | 
| +  // Set break point. | 
| +  if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg, | 
| +                                                &source_position)) { | 
| +    return  isolate->heap()->undefined_value(); | 
| } | 
| -  return  isolate->heap()->undefined_value(); | 
| + | 
| +  return Smi::FromInt(source_position); | 
| } | 
|  | 
|  | 
| @@ -12540,7 +12549,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) { | 
| ASSERT(args.length() == 1); | 
| // Get the function and make sure it is compiled. | 
| CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0); | 
| -  if (!JSFunction::CompileLazy(func, KEEP_EXCEPTION)) { | 
| +  if (!JSFunction::EnsureCompiled(func, KEEP_EXCEPTION)) { | 
| return Failure::Exception(); | 
| } | 
| func->code()->PrintLn(); | 
| @@ -12555,7 +12564,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) { | 
| ASSERT(args.length() == 1); | 
| // Get the function and make sure it is compiled. | 
| CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0); | 
| -  if (!JSFunction::CompileLazy(func, KEEP_EXCEPTION)) { | 
| +  if (!JSFunction::EnsureCompiled(func, KEEP_EXCEPTION)) { | 
| return Failure::Exception(); | 
| } | 
| func->shared()->construct_stub()->PrintLn(); | 
|  |