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 |