OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 9721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9732 Object* Runtime::FindSharedFunctionInfoInScript(Handle<Script> script, | 9732 Object* Runtime::FindSharedFunctionInfoInScript(Handle<Script> script, |
9733 int position) { | 9733 int position) { |
9734 // Iterate the heap looking for SharedFunctionInfo generated from the | 9734 // Iterate the heap looking for SharedFunctionInfo generated from the |
9735 // script. The inner most SharedFunctionInfo containing the source position | 9735 // script. The inner most SharedFunctionInfo containing the source position |
9736 // for the requested break point is found. | 9736 // for the requested break point is found. |
9737 // NOTE: This might require several heap iterations. If the SharedFunctionInfo | 9737 // NOTE: This might require several heap iterations. If the SharedFunctionInfo |
9738 // which is found is not compiled it is compiled and the heap is iterated | 9738 // which is found is not compiled it is compiled and the heap is iterated |
9739 // again as the compilation might create inner functions from the newly | 9739 // again as the compilation might create inner functions from the newly |
9740 // compiled function and the actual requested break point might be in one of | 9740 // compiled function and the actual requested break point might be in one of |
9741 // these functions. | 9741 // these functions. |
9742 Heap::EnsureHeapIsIterable(); | |
9742 bool done = false; | 9743 bool done = false; |
9743 // The current candidate for the source position: | 9744 // The current candidate for the source position: |
9744 int target_start_position = RelocInfo::kNoPosition; | 9745 int target_start_position = RelocInfo::kNoPosition; |
9745 Handle<SharedFunctionInfo> target; | 9746 Handle<SharedFunctionInfo> target; |
9746 while (!done) { | 9747 while (!done) { |
9747 HeapIterator iterator; | 9748 HeapIterator iterator; |
9748 for (HeapObject* obj = iterator.next(); | 9749 for (HeapObject* obj = iterator.Next(); |
9749 obj != NULL; obj = iterator.next()) { | 9750 obj != NULL; obj = iterator.Next()) { |
9750 if (obj->IsSharedFunctionInfo()) { | 9751 if (obj->IsSharedFunctionInfo()) { |
9751 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj)); | 9752 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj)); |
9752 if (shared->script() == *script) { | 9753 if (shared->script() == *script) { |
9753 // If the SharedFunctionInfo found has the requested script data and | 9754 // If the SharedFunctionInfo found has the requested script data and |
9754 // contains the source position it is a candidate. | 9755 // contains the source position it is a candidate. |
9755 int start_position = shared->function_token_position(); | 9756 int start_position = shared->function_token_position(); |
9756 if (start_position == RelocInfo::kNoPosition) { | 9757 if (start_position == RelocInfo::kNoPosition) { |
9757 start_position = shared->start_position(); | 9758 start_position = shared->start_position(); |
9758 } | 9759 } |
9759 if (start_position <= position && | 9760 if (start_position <= position && |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10235 FixedArray* instances, int instances_size, | 10236 FixedArray* instances, int instances_size, |
10236 JSFunction* arguments_function) { | 10237 JSFunction* arguments_function) { |
10237 NoHandleAllocation ha; | 10238 NoHandleAllocation ha; |
10238 AssertNoAllocation no_alloc; | 10239 AssertNoAllocation no_alloc; |
10239 | 10240 |
10240 // Iterate the heap. | 10241 // Iterate the heap. |
10241 int count = 0; | 10242 int count = 0; |
10242 JSObject* last = NULL; | 10243 JSObject* last = NULL; |
10243 HeapIterator iterator; | 10244 HeapIterator iterator; |
10244 HeapObject* heap_obj = NULL; | 10245 HeapObject* heap_obj = NULL; |
10245 while (((heap_obj = iterator.next()) != NULL) && | 10246 while (((heap_obj = iterator.Next()) != NULL) && |
10246 (max_references == 0 || count < max_references)) { | 10247 (max_references == 0 || count < max_references)) { |
10247 // Only look at all JSObjects. | 10248 // Only look at all JSObjects. |
10248 if (heap_obj->IsJSObject()) { | 10249 if (heap_obj->IsJSObject()) { |
10249 // Skip context extension objects and argument arrays as these are | 10250 // Skip context extension objects and argument arrays as these are |
10250 // checked in the context of functions using them. | 10251 // checked in the context of functions using them. |
10251 JSObject* obj = JSObject::cast(heap_obj); | 10252 JSObject* obj = JSObject::cast(heap_obj); |
10252 if (obj->IsJSContextExtensionObject() || | 10253 if (obj->IsJSContextExtensionObject() || |
10253 obj->map()->constructor() == arguments_function) { | 10254 obj->map()->constructor() == arguments_function) { |
10254 continue; | 10255 continue; |
10255 } | 10256 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10300 | 10301 |
10301 | 10302 |
10302 // Scan the heap for objects with direct references to an object | 10303 // Scan the heap for objects with direct references to an object |
10303 // args[0]: the object to find references to | 10304 // args[0]: the object to find references to |
10304 // args[1]: constructor function for instances to exclude (Mirror) | 10305 // args[1]: constructor function for instances to exclude (Mirror) |
10305 // args[2]: the the maximum number of objects to return | 10306 // args[2]: the the maximum number of objects to return |
10306 static MaybeObject* Runtime_DebugReferencedBy(Arguments args) { | 10307 static MaybeObject* Runtime_DebugReferencedBy(Arguments args) { |
10307 ASSERT(args.length() == 3); | 10308 ASSERT(args.length() == 3); |
10308 | 10309 |
10309 // First perform a full GC in order to avoid references from dead objects. | 10310 // First perform a full GC in order to avoid references from dead objects. |
10310 Heap::CollectAllGarbage(false); | 10311 Heap::CollectAllGarbage(Heap::kSweepPreciselyMask); |
10311 | 10312 |
10312 // Check parameters. | 10313 // Check parameters. |
10313 CONVERT_CHECKED(JSObject, target, args[0]); | 10314 CONVERT_CHECKED(JSObject, target, args[0]); |
10314 Object* instance_filter = args[1]; | 10315 Object* instance_filter = args[1]; |
10315 RUNTIME_ASSERT(instance_filter->IsUndefined() || | 10316 RUNTIME_ASSERT(instance_filter->IsUndefined() || |
10316 instance_filter->IsJSObject()); | 10317 instance_filter->IsJSObject()); |
10317 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); | 10318 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); |
10318 RUNTIME_ASSERT(max_references >= 0); | 10319 RUNTIME_ASSERT(max_references >= 0); |
10319 | 10320 |
10320 // Get the constructor function for context extension and arguments array. | 10321 // Get the constructor function for context extension and arguments array. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10352 | 10353 |
10353 // Helper function used by Runtime_DebugConstructedBy below. | 10354 // Helper function used by Runtime_DebugConstructedBy below. |
10354 static int DebugConstructedBy(JSFunction* constructor, int max_references, | 10355 static int DebugConstructedBy(JSFunction* constructor, int max_references, |
10355 FixedArray* instances, int instances_size) { | 10356 FixedArray* instances, int instances_size) { |
10356 AssertNoAllocation no_alloc; | 10357 AssertNoAllocation no_alloc; |
10357 | 10358 |
10358 // Iterate the heap. | 10359 // Iterate the heap. |
10359 int count = 0; | 10360 int count = 0; |
10360 HeapIterator iterator; | 10361 HeapIterator iterator; |
10361 HeapObject* heap_obj = NULL; | 10362 HeapObject* heap_obj = NULL; |
10362 while (((heap_obj = iterator.next()) != NULL) && | 10363 while (((heap_obj = iterator.Next()) != NULL) && |
10363 (max_references == 0 || count < max_references)) { | 10364 (max_references == 0 || count < max_references)) { |
10364 // Only look at all JSObjects. | 10365 // Only look at all JSObjects. |
10365 if (heap_obj->IsJSObject()) { | 10366 if (heap_obj->IsJSObject()) { |
10366 JSObject* obj = JSObject::cast(heap_obj); | 10367 JSObject* obj = JSObject::cast(heap_obj); |
10367 if (obj->map()->constructor() == constructor) { | 10368 if (obj->map()->constructor() == constructor) { |
10368 // Valid reference found add to instance array if supplied an update | 10369 // Valid reference found add to instance array if supplied an update |
10369 // count. | 10370 // count. |
10370 if (instances != NULL && count < instances_size) { | 10371 if (instances != NULL && count < instances_size) { |
10371 instances->set(count, obj); | 10372 instances->set(count, obj); |
10372 } | 10373 } |
10373 count++; | 10374 count++; |
10374 } | 10375 } |
10375 } | 10376 } |
10376 } | 10377 } |
10377 | 10378 |
10378 // Return the number of referencing objects found. | 10379 // Return the number of referencing objects found. |
10379 return count; | 10380 return count; |
10380 } | 10381 } |
10381 | 10382 |
10382 | 10383 |
10383 // Scan the heap for objects constructed by a specific function. | 10384 // Scan the heap for objects constructed by a specific function. |
10384 // args[0]: the constructor to find instances of | 10385 // args[0]: the constructor to find instances of |
10385 // args[1]: the the maximum number of objects to return | 10386 // args[1]: the the maximum number of objects to return |
10386 static MaybeObject* Runtime_DebugConstructedBy(Arguments args) { | 10387 static MaybeObject* Runtime_DebugConstructedBy(Arguments args) { |
10387 ASSERT(args.length() == 2); | 10388 ASSERT(args.length() == 2); |
10388 | 10389 |
10389 // First perform a full GC in order to avoid dead objects. | 10390 // First perform a full GC in order to avoid dead objects. |
10390 Heap::CollectAllGarbage(false); | 10391 Heap::CollectAllGarbage(Heap::kSweepPreciselyMask); |
10391 | 10392 |
10392 // Check parameters. | 10393 // Check parameters. |
10393 CONVERT_CHECKED(JSFunction, constructor, args[0]); | 10394 CONVERT_CHECKED(JSFunction, constructor, args[0]); |
10394 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); | 10395 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); |
10395 RUNTIME_ASSERT(max_references >= 0); | 10396 RUNTIME_ASSERT(max_references >= 0); |
10396 | 10397 |
10397 // Get the number of referencing objects. | 10398 // Get the number of referencing objects. |
10398 int count; | 10399 int count; |
10399 count = DebugConstructedBy(constructor, max_references, NULL, 0); | 10400 count = DebugConstructedBy(constructor, max_references, NULL, 0); |
10400 | 10401 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10479 } | 10480 } |
10480 | 10481 |
10481 | 10482 |
10482 static int FindSharedFunctionInfosForScript(Script* script, | 10483 static int FindSharedFunctionInfosForScript(Script* script, |
10483 FixedArray* buffer) { | 10484 FixedArray* buffer) { |
10484 AssertNoAllocation no_allocations; | 10485 AssertNoAllocation no_allocations; |
10485 | 10486 |
10486 int counter = 0; | 10487 int counter = 0; |
10487 int buffer_size = buffer->length(); | 10488 int buffer_size = buffer->length(); |
10488 HeapIterator iterator; | 10489 HeapIterator iterator; |
10489 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 10490 for (HeapObject* obj = iterator.Next(); obj != NULL; obj = iterator.Next()) { |
10490 ASSERT(obj != NULL); | 10491 ASSERT(obj != NULL); |
10491 if (!obj->IsSharedFunctionInfo()) { | 10492 if (!obj->IsSharedFunctionInfo()) { |
10492 continue; | 10493 continue; |
10493 } | 10494 } |
10494 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | 10495 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
10495 if (shared->script() != script) { | 10496 if (shared->script() != script) { |
10496 continue; | 10497 continue; |
10497 } | 10498 } |
10498 if (counter < buffer_size) { | 10499 if (counter < buffer_size) { |
10499 buffer->set(counter, shared); | 10500 buffer->set(counter, shared); |
10500 } | 10501 } |
10501 counter++; | 10502 counter++; |
10502 } | 10503 } |
10503 return counter; | 10504 return counter; |
10504 } | 10505 } |
10505 | 10506 |
10506 // For a script finds all SharedFunctionInfo's in the heap that points | 10507 // For a script finds all SharedFunctionInfo's in the heap that points |
10507 // to this script. Returns JSArray of SharedFunctionInfo wrapped | 10508 // to this script. Returns JSArray of SharedFunctionInfo wrapped |
10508 // in OpaqueReferences. | 10509 // in OpaqueReferences. |
10509 static MaybeObject* Runtime_LiveEditFindSharedFunctionInfosForScript( | 10510 static MaybeObject* Runtime_LiveEditFindSharedFunctionInfosForScript( |
10510 Arguments args) { | 10511 Arguments args) { |
10511 ASSERT(args.length() == 1); | 10512 ASSERT(args.length() == 1); |
10512 HandleScope scope; | 10513 HandleScope scope; |
10513 CONVERT_CHECKED(JSValue, script_value, args[0]); | 10514 CONVERT_CHECKED(JSValue, script_value, args[0]); |
10514 | 10515 |
10516 | |
10515 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); | 10517 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); |
10516 | 10518 |
10517 const int kBufferSize = 32; | 10519 const int kBufferSize = 32; |
10518 | 10520 |
10519 Handle<FixedArray> array; | 10521 Handle<FixedArray> array; |
10520 array = Factory::NewFixedArray(kBufferSize); | 10522 array = Factory::NewFixedArray(kBufferSize); |
10523 Heap::EnsureHeapIsIterable(); | |
10521 int number = FindSharedFunctionInfosForScript(*script, *array); | 10524 int number = FindSharedFunctionInfosForScript(*script, *array); |
10522 if (number > kBufferSize) { | 10525 if (number > kBufferSize) { |
10523 array = Factory::NewFixedArray(number); | 10526 array = Factory::NewFixedArray(number); |
10527 Heap::EnsureHeapIsIterable(); | |
Vyacheslav Egorov (Chromium)
2011/03/15 09:20:09
This is very fragile. We definitely should encapsu
Erik Corry
2011/03/17 13:39:17
Done.
| |
10524 FindSharedFunctionInfosForScript(*script, *array); | 10528 FindSharedFunctionInfosForScript(*script, *array); |
10525 } | 10529 } |
10526 | 10530 |
10527 Handle<JSArray> result = Factory::NewJSArrayWithElements(array); | 10531 Handle<JSArray> result = Factory::NewJSArrayWithElements(array); |
10528 result->set_length(Smi::FromInt(number)); | 10532 result->set_length(Smi::FromInt(number)); |
10529 | 10533 |
10530 LiveEdit::WrapSharedFunctionInfos(result); | 10534 LiveEdit::WrapSharedFunctionInfos(result); |
10531 | 10535 |
10532 return *result; | 10536 return *result; |
10533 } | 10537 } |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10754 SmartPointer<char> flags = | 10758 SmartPointer<char> flags = |
10755 arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 10759 arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
10756 FlagList::SetFlagsFromString(*flags, StrLength(*flags)); | 10760 FlagList::SetFlagsFromString(*flags, StrLength(*flags)); |
10757 return Heap::undefined_value(); | 10761 return Heap::undefined_value(); |
10758 } | 10762 } |
10759 | 10763 |
10760 | 10764 |
10761 // Performs a GC. | 10765 // Performs a GC. |
10762 // Presently, it only does a full GC. | 10766 // Presently, it only does a full GC. |
10763 static MaybeObject* Runtime_CollectGarbage(Arguments args) { | 10767 static MaybeObject* Runtime_CollectGarbage(Arguments args) { |
10764 Heap::CollectAllGarbage(true); | 10768 Heap::CollectAllGarbage(Heap::kForceCompactionMask); |
10765 return Heap::undefined_value(); | 10769 return Heap::undefined_value(); |
10766 } | 10770 } |
10767 | 10771 |
10768 | 10772 |
10769 // Gets the current heap usage. | 10773 // Gets the current heap usage. |
10770 static MaybeObject* Runtime_GetHeapUsage(Arguments args) { | 10774 static MaybeObject* Runtime_GetHeapUsage(Arguments args) { |
10771 int usage = static_cast<int>(Heap::SizeOfObjects()); | 10775 int usage = static_cast<int>(Heap::SizeOfObjects()); |
10772 if (!Smi::IsValid(usage)) { | 10776 if (!Smi::IsValid(usage)) { |
10773 return *Factory::NewNumberFromInt(usage); | 10777 return *Factory::NewNumberFromInt(usage); |
10774 } | 10778 } |
(...skipping 27 matching lines...) Expand all Loading... | |
10802 #endif // ENABLE_LOGGING_AND_PROFILING | 10806 #endif // ENABLE_LOGGING_AND_PROFILING |
10803 | 10807 |
10804 // Finds the script object from the script data. NOTE: This operation uses | 10808 // Finds the script object from the script data. NOTE: This operation uses |
10805 // heap traversal to find the function generated for the source position | 10809 // heap traversal to find the function generated for the source position |
10806 // for the requested break point. For lazily compiled functions several heap | 10810 // for the requested break point. For lazily compiled functions several heap |
10807 // traversals might be required rendering this operation as a rather slow | 10811 // traversals might be required rendering this operation as a rather slow |
10808 // operation. However for setting break points which is normally done through | 10812 // operation. However for setting break points which is normally done through |
10809 // some kind of user interaction the performance is not crucial. | 10813 // some kind of user interaction the performance is not crucial. |
10810 static Handle<Object> Runtime_GetScriptFromScriptName( | 10814 static Handle<Object> Runtime_GetScriptFromScriptName( |
10811 Handle<String> script_name) { | 10815 Handle<String> script_name) { |
10816 Heap::EnsureHeapIsIterable(); | |
10812 // Scan the heap for Script objects to find the script with the requested | 10817 // Scan the heap for Script objects to find the script with the requested |
10813 // script data. | 10818 // script data. |
10814 Handle<Script> script; | 10819 Handle<Script> script; |
10815 HeapIterator iterator; | 10820 HeapIterator iterator; |
10816 HeapObject* obj = NULL; | 10821 HeapObject* obj = NULL; |
10817 while (script.is_null() && ((obj = iterator.next()) != NULL)) { | 10822 while (script.is_null() && ((obj = iterator.Next()) != NULL)) { |
10818 // If a script is found check if it has the script data requested. | 10823 // If a script is found check if it has the script data requested. |
10819 if (obj->IsScript()) { | 10824 if (obj->IsScript()) { |
10820 if (Script::cast(obj)->name()->IsString()) { | 10825 if (Script::cast(obj)->name()->IsString()) { |
10821 if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) { | 10826 if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) { |
10822 script = Handle<Script>(Script::cast(obj)); | 10827 script = Handle<Script>(Script::cast(obj)); |
10823 } | 10828 } |
10824 } | 10829 } |
10825 } | 10830 } |
10826 } | 10831 } |
10827 | 10832 |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11201 void Runtime::PerformGC(Object* result) { | 11206 void Runtime::PerformGC(Object* result) { |
11202 Failure* failure = Failure::cast(result); | 11207 Failure* failure = Failure::cast(result); |
11203 if (failure->IsRetryAfterGC()) { | 11208 if (failure->IsRetryAfterGC()) { |
11204 // Try to do a garbage collection; ignore it if it fails. The C | 11209 // Try to do a garbage collection; ignore it if it fails. The C |
11205 // entry stub will throw an out-of-memory exception in that case. | 11210 // entry stub will throw an out-of-memory exception in that case. |
11206 Heap::CollectGarbage(failure->allocation_space()); | 11211 Heap::CollectGarbage(failure->allocation_space()); |
11207 } else { | 11212 } else { |
11208 // Handle last resort GC and make sure to allow future allocations | 11213 // Handle last resort GC and make sure to allow future allocations |
11209 // to grow the heap without causing GCs (if possible). | 11214 // to grow the heap without causing GCs (if possible). |
11210 Counters::gc_last_resort_from_js.Increment(); | 11215 Counters::gc_last_resort_from_js.Increment(); |
11211 Heap::CollectAllGarbage(false); | 11216 Heap::CollectAllGarbage(Heap::kNoGCFlags); |
11212 } | 11217 } |
11213 } | 11218 } |
11214 | 11219 |
11215 | 11220 |
11216 } } // namespace v8::internal | 11221 } } // namespace v8::internal |
OLD | NEW |