| OLD | NEW | 
|      1 // Copyright 2012 the V8 project authors. All rights reserved. |      1 // Copyright 2012 the V8 project authors. All rights reserved. | 
|      2 // Redistribution and use in source and binary forms, with or without |      2 // Redistribution and use in source and binary forms, with or without | 
|      3 // modification, are permitted provided that the following conditions are |      3 // modification, are permitted provided that the following conditions are | 
|      4 // met: |      4 // met: | 
|      5 // |      5 // | 
|      6 //     * Redistributions of source code must retain the above copyright |      6 //     * Redistributions of source code must retain the above copyright | 
|      7 //       notice, this list of conditions and the following disclaimer. |      7 //       notice, this list of conditions and the following disclaimer. | 
|      8 //     * Redistributions in binary form must reproduce the above |      8 //     * Redistributions in binary form must reproduce the above | 
|      9 //       copyright notice, this list of conditions and the following |      9 //       copyright notice, this list of conditions and the following | 
|     10 //       disclaimer in the documentation and/or other materials provided |     10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 11403 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  11414   Handle<SharedFunctionInfo> shared(fun->shared()); |  11414   Handle<SharedFunctionInfo> shared(fun->shared()); | 
|  11415   // Find the number of break points |  11415   // Find the number of break points | 
|  11416   Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared); |  11416   Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared); | 
|  11417   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value(); |  11417   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value(); | 
|  11418   // Return array as JS array |  11418   // Return array as JS array | 
|  11419   return *isolate->factory()->NewJSArrayWithElements( |  11419   return *isolate->factory()->NewJSArrayWithElements( | 
|  11420       Handle<FixedArray>::cast(break_locations)); |  11420       Handle<FixedArray>::cast(break_locations)); | 
|  11421 } |  11421 } | 
|  11422  |  11422  | 
|  11423  |  11423  | 
|  11424 Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate, |  | 
|  11425                                                 Handle<Script> script, |  | 
|  11426                                                 int position) { |  | 
|  11427   // The below fix-point iteration depends on all functions that cannot be |  | 
|  11428   // compiled lazily without a context to not be compiled at all. Compilation |  | 
|  11429   // will be triggered at points where we do not need a context. |  | 
|  11430   isolate->debug()->PrepareForBreakPoints(); |  | 
|  11431  |  | 
|  11432   // Iterate the heap looking for SharedFunctionInfo generated from the |  | 
|  11433   // script. The inner most SharedFunctionInfo containing the source position |  | 
|  11434   // for the requested break point is found. |  | 
|  11435   // NOTE: This might require several heap iterations. If the SharedFunctionInfo |  | 
|  11436   // which is found is not compiled it is compiled and the heap is iterated |  | 
|  11437   // again as the compilation might create inner functions from the newly |  | 
|  11438   // compiled function and the actual requested break point might be in one of |  | 
|  11439   // these functions. |  | 
|  11440   bool done = false; |  | 
|  11441   // The current candidate for the source position: |  | 
|  11442   int target_start_position = RelocInfo::kNoPosition; |  | 
|  11443   Handle<JSFunction> target_function; |  | 
|  11444   Handle<SharedFunctionInfo> target; |  | 
|  11445   while (!done) { |  | 
|  11446     { // Extra scope for iterator and no-allocation. |  | 
|  11447       isolate->heap()->EnsureHeapIsIterable(); |  | 
|  11448       AssertNoAllocation no_alloc_during_heap_iteration; |  | 
|  11449       HeapIterator iterator; |  | 
|  11450       for (HeapObject* obj = iterator.next(); |  | 
|  11451            obj != NULL; obj = iterator.next()) { |  | 
|  11452         bool found_next_candidate = false; |  | 
|  11453         Handle<JSFunction> function; |  | 
|  11454         Handle<SharedFunctionInfo> shared; |  | 
|  11455         if (obj->IsJSFunction()) { |  | 
|  11456           function = Handle<JSFunction>(JSFunction::cast(obj)); |  | 
|  11457           shared = Handle<SharedFunctionInfo>(function->shared()); |  | 
|  11458           ASSERT(shared->allows_lazy_compilation() || shared->is_compiled()); |  | 
|  11459           found_next_candidate = true; |  | 
|  11460         } else if (obj->IsSharedFunctionInfo()) { |  | 
|  11461           shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(obj)); |  | 
|  11462           // Skip functions that we cannot compile lazily without a context, |  | 
|  11463           // which is not available here, because there is no closure. |  | 
|  11464           found_next_candidate = shared->is_compiled() || |  | 
|  11465               shared->allows_lazy_compilation_without_context(); |  | 
|  11466         } |  | 
|  11467         if (!found_next_candidate) continue; |  | 
|  11468         if (shared->script() == *script) { |  | 
|  11469           // If the SharedFunctionInfo found has the requested script data and |  | 
|  11470           // contains the source position it is a candidate. |  | 
|  11471           int start_position = shared->function_token_position(); |  | 
|  11472           if (start_position == RelocInfo::kNoPosition) { |  | 
|  11473             start_position = shared->start_position(); |  | 
|  11474           } |  | 
|  11475           if (start_position <= position && |  | 
|  11476               position <= shared->end_position()) { |  | 
|  11477             // If there is no candidate or this function is within the current |  | 
|  11478             // candidate this is the new candidate. |  | 
|  11479             if (target.is_null()) { |  | 
|  11480               target_start_position = start_position; |  | 
|  11481               target_function = function; |  | 
|  11482               target = shared; |  | 
|  11483             } else { |  | 
|  11484               if (target_start_position == start_position && |  | 
|  11485                   shared->end_position() == target->end_position()) { |  | 
|  11486                 // If a top-level function contains only one function |  | 
|  11487                 // declaration the source for the top-level and the function |  | 
|  11488                 // is the same. In that case prefer the non top-level function. |  | 
|  11489                 if (!shared->is_toplevel()) { |  | 
|  11490                   target_start_position = start_position; |  | 
|  11491                   target_function = function; |  | 
|  11492                   target = shared; |  | 
|  11493                 } |  | 
|  11494               } else if (target_start_position <= start_position && |  | 
|  11495                          shared->end_position() <= target->end_position()) { |  | 
|  11496                 // This containment check includes equality as a function |  | 
|  11497                 // inside a top-level function can share either start or end |  | 
|  11498                 // position with the top-level function. |  | 
|  11499                 target_start_position = start_position; |  | 
|  11500                 target_function = function; |  | 
|  11501                 target = shared; |  | 
|  11502               } |  | 
|  11503             } |  | 
|  11504           } |  | 
|  11505         } |  | 
|  11506       }  // End for loop. |  | 
|  11507     }  // End no-allocation scope. |  | 
|  11508  |  | 
|  11509     if (target.is_null()) { |  | 
|  11510       return isolate->heap()->undefined_value(); |  | 
|  11511     } |  | 
|  11512  |  | 
|  11513     // If the candidate found is compiled we are done. |  | 
|  11514     done = target->is_compiled(); |  | 
|  11515     if (!done) { |  | 
|  11516       // If the candidate is not compiled, compile it to reveal any inner |  | 
|  11517       // functions which might contain the requested source position. This |  | 
|  11518       // will compile all inner functions that cannot be compiled without a |  | 
|  11519       // context, because Compiler::BuildFunctionInfo checks whether the |  | 
|  11520       // debugger is active. |  | 
|  11521       if (target_function.is_null()) { |  | 
|  11522         SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION); |  | 
|  11523       } else { |  | 
|  11524         JSFunction::CompileLazy(target_function, KEEP_EXCEPTION); |  | 
|  11525       } |  | 
|  11526     } |  | 
|  11527   }  // End while loop. |  | 
|  11528  |  | 
|  11529   return *target; |  | 
|  11530 } |  | 
|  11531  |  | 
|  11532  |  | 
|  11533 // Set a break point in a function. |  11424 // Set a break point in a function. | 
|  11534 // args[0]: function |  11425 // args[0]: function | 
|  11535 // args[1]: number: break source position (within the function source) |  11426 // args[1]: number: break source position (within the function source) | 
|  11536 // args[2]: number: break point object |  11427 // args[2]: number: break point object | 
|  11537 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) { |  11428 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) { | 
|  11538   HandleScope scope(isolate); |  11429   HandleScope scope(isolate); | 
|  11539   ASSERT(args.length() == 3); |  11430   ASSERT(args.length() == 3); | 
|  11540   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |  11431   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | 
|  11541   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); |  11432   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 
|  11542   RUNTIME_ASSERT(source_position >= 0); |  11433   RUNTIME_ASSERT(source_position >= 0); | 
| (...skipping 1853 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  13396     // Handle last resort GC and make sure to allow future allocations |  13287     // Handle last resort GC and make sure to allow future allocations | 
|  13397     // to grow the heap without causing GCs (if possible). |  13288     // to grow the heap without causing GCs (if possible). | 
|  13398     isolate->counters()->gc_last_resort_from_js()->Increment(); |  13289     isolate->counters()->gc_last_resort_from_js()->Increment(); | 
|  13399     isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |  13290     isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 
|  13400                                        "Runtime::PerformGC"); |  13291                                        "Runtime::PerformGC"); | 
|  13401   } |  13292   } | 
|  13402 } |  13293 } | 
|  13403  |  13294  | 
|  13404  |  13295  | 
|  13405 } }  // namespace v8::internal |  13296 } }  // namespace v8::internal | 
| OLD | NEW |