Chromium Code Reviews| 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 |