| 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 |