Chromium Code Reviews| 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 13031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13042 // Return the number of referencing objects found. | 13042 // Return the number of referencing objects found. |
| 13043 return count; | 13043 return count; |
| 13044 } | 13044 } |
| 13045 | 13045 |
| 13046 | 13046 |
| 13047 // Scan the heap for objects with direct references to an object | 13047 // Scan the heap for objects with direct references to an object |
| 13048 // args[0]: the object to find references to | 13048 // args[0]: the object to find references to |
| 13049 // args[1]: constructor function for instances to exclude (Mirror) | 13049 // args[1]: constructor function for instances to exclude (Mirror) |
| 13050 // args[2]: the the maximum number of objects to return | 13050 // args[2]: the the maximum number of objects to return |
| 13051 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) { | 13051 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) { |
| 13052 SealHandleScope shs(isolate); | 13052 HandleScope scope(isolate); |
| 13053 ASSERT(args.length() == 3); | 13053 ASSERT(args.length() == 3); |
| 13054 | 13054 |
| 13055 // First perform a full GC in order to avoid references from dead objects. | 13055 // First perform a full GC in order to avoid references from dead objects. |
| 13056 isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 13056 Heap* heap = isolate->heap(); |
| 13057 "%DebugReferencedBy"); | 13057 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugReferencedBy"); |
| 13058 // The heap iterator reserves the right to do a GC to make the heap iterable. | 13058 // The heap iterator reserves the right to do a GC to make the heap iterable. |
| 13059 // Due to the GC above we know it won't need to do that, but it seems cleaner | 13059 // Due to the GC above we know it won't need to do that, but it seems cleaner |
| 13060 // to get the heap iterator constructed before we start having unprotected | 13060 // to get the heap iterator constructed before we start having unprotected |
| 13061 // Object* locals that are not protected by handles. | 13061 // Object* locals that are not protected by handles. |
| 13062 | 13062 |
| 13063 // Check parameters. | 13063 // Check parameters. |
| 13064 CONVERT_ARG_CHECKED(JSObject, target, 0); | 13064 CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0); |
| 13065 Object* instance_filter = args[1]; | 13065 Handle<Object> instance_filter = args.at<Object>(1); |
| 13066 RUNTIME_ASSERT(instance_filter->IsUndefined() || | 13066 RUNTIME_ASSERT(instance_filter->IsUndefined() || |
| 13067 instance_filter->IsJSObject()); | 13067 instance_filter->IsJSObject()); |
| 13068 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); | 13068 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); |
| 13069 RUNTIME_ASSERT(max_references >= 0); | 13069 RUNTIME_ASSERT(max_references >= 0); |
| 13070 | 13070 |
| 13071 | 13071 |
| 13072 // Get the constructor function for context extension and arguments array. | 13072 // Get the constructor function for context extension and arguments array. |
| 13073 JSObject* arguments_boilerplate = | 13073 Handle<JSObject> arguments_boilerplate( |
| 13074 isolate->context()->native_context()->sloppy_arguments_boilerplate(); | 13074 isolate->context()->native_context()->sloppy_arguments_boilerplate()); |
| 13075 JSFunction* arguments_function = | 13075 Handle<JSFunction> arguments_function( |
| 13076 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 13076 JSFunction::cast(arguments_boilerplate->map()->constructor())); |
| 13077 | 13077 |
| 13078 // Get the number of referencing objects. | 13078 // Get the number of referencing objects. |
| 13079 int count; | 13079 int count; |
| 13080 Heap* heap = isolate->heap(); | |
| 13081 HeapIterator heap_iterator(heap); | 13080 HeapIterator heap_iterator(heap); |
| 13082 count = DebugReferencedBy(&heap_iterator, | 13081 count = DebugReferencedBy(&heap_iterator, |
| 13083 target, instance_filter, max_references, | 13082 *target, *instance_filter, max_references, |
| 13084 NULL, 0, arguments_function); | 13083 NULL, 0, *arguments_function); |
| 13085 | 13084 |
| 13086 // Allocate an array to hold the result. | 13085 // Allocate an array to hold the result. |
| 13087 Object* object; | 13086 Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count); |
| 13088 { MaybeObject* maybe_object = heap->AllocateFixedArray(count); | |
| 13089 if (!maybe_object->ToObject(&object)) return maybe_object; | |
| 13090 } | |
| 13091 FixedArray* instances = FixedArray::cast(object); | |
| 13092 | 13087 |
| 13093 // Fill the referencing objects. | 13088 // Fill the referencing objects. |
| 13094 // AllocateFixedArray above does not make the heap non-iterable. | 13089 // AllocateFixedArray above does not make the heap non-iterable. |
| 13095 ASSERT(heap->IsHeapIterable()); | 13090 ASSERT(heap->IsHeapIterable()); |
| 13096 HeapIterator heap_iterator2(heap); | 13091 HeapIterator heap_iterator2(heap); |
| 13097 count = DebugReferencedBy(&heap_iterator2, | 13092 count = DebugReferencedBy(&heap_iterator2, |
| 13098 target, instance_filter, max_references, | 13093 *target, *instance_filter, max_references, |
| 13099 instances, count, arguments_function); | 13094 *instances, count, *arguments_function); |
| 13100 | 13095 |
| 13101 // Return result as JS array. | 13096 // Return result as JS array. |
| 13102 Object* result; | 13097 Handle<JSFunction> constructor( |
| 13103 MaybeObject* maybe_result = heap->AllocateJSObject( | |
| 13104 isolate->context()->native_context()->array_function()); | 13098 isolate->context()->native_context()->array_function()); |
| 13105 if (!maybe_result->ToObject(&result)) return maybe_result; | 13099 |
| 13106 return JSArray::cast(result)->SetContent(instances); | 13100 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor); |
| 13101 isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances); | |
|
Yang
2014/03/20 13:22:07
for the sake of consistency, could we move SetCont
Igor Sheludko
2014/03/20 13:28:14
It is done in a next CL where I handlified JSArray
| |
| 13102 return *result; | |
| 13107 } | 13103 } |
| 13108 | 13104 |
| 13109 | 13105 |
| 13110 // Helper function used by Runtime_DebugConstructedBy below. | 13106 // Helper function used by Runtime_DebugConstructedBy below. |
| 13111 static int DebugConstructedBy(HeapIterator* iterator, | 13107 static int DebugConstructedBy(HeapIterator* iterator, |
| 13112 JSFunction* constructor, | 13108 JSFunction* constructor, |
| 13113 int max_references, | 13109 int max_references, |
| 13114 FixedArray* instances, | 13110 FixedArray* instances, |
| 13115 int instances_size) { | 13111 int instances_size) { |
| 13116 DisallowHeapAllocation no_allocation; | 13112 DisallowHeapAllocation no_allocation; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 13136 | 13132 |
| 13137 // Return the number of referencing objects found. | 13133 // Return the number of referencing objects found. |
| 13138 return count; | 13134 return count; |
| 13139 } | 13135 } |
| 13140 | 13136 |
| 13141 | 13137 |
| 13142 // Scan the heap for objects constructed by a specific function. | 13138 // Scan the heap for objects constructed by a specific function. |
| 13143 // args[0]: the constructor to find instances of | 13139 // args[0]: the constructor to find instances of |
| 13144 // args[1]: the the maximum number of objects to return | 13140 // args[1]: the the maximum number of objects to return |
| 13145 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) { | 13141 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) { |
| 13146 SealHandleScope shs(isolate); | 13142 HandleScope scope(isolate); |
| 13147 ASSERT(args.length() == 2); | 13143 ASSERT(args.length() == 2); |
| 13148 | 13144 |
| 13149 // First perform a full GC in order to avoid dead objects. | 13145 // First perform a full GC in order to avoid dead objects. |
| 13150 Heap* heap = isolate->heap(); | 13146 Heap* heap = isolate->heap(); |
| 13151 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy"); | 13147 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy"); |
| 13152 | 13148 |
| 13153 // Check parameters. | 13149 // Check parameters. |
| 13154 CONVERT_ARG_CHECKED(JSFunction, constructor, 0); | 13150 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0); |
| 13155 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); | 13151 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); |
| 13156 RUNTIME_ASSERT(max_references >= 0); | 13152 RUNTIME_ASSERT(max_references >= 0); |
| 13157 | 13153 |
| 13158 // Get the number of referencing objects. | 13154 // Get the number of referencing objects. |
| 13159 int count; | 13155 int count; |
| 13160 HeapIterator heap_iterator(heap); | 13156 HeapIterator heap_iterator(heap); |
| 13161 count = DebugConstructedBy(&heap_iterator, | 13157 count = DebugConstructedBy(&heap_iterator, |
| 13162 constructor, | 13158 *constructor, |
| 13163 max_references, | 13159 max_references, |
| 13164 NULL, | 13160 NULL, |
| 13165 0); | 13161 0); |
| 13166 | 13162 |
| 13167 // Allocate an array to hold the result. | 13163 // Allocate an array to hold the result. |
| 13168 Object* object; | 13164 Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count); |
| 13169 { MaybeObject* maybe_object = heap->AllocateFixedArray(count); | |
| 13170 if (!maybe_object->ToObject(&object)) return maybe_object; | |
| 13171 } | |
| 13172 FixedArray* instances = FixedArray::cast(object); | |
| 13173 | 13165 |
| 13174 ASSERT(isolate->heap()->IsHeapIterable()); | 13166 ASSERT(heap->IsHeapIterable()); |
| 13175 // Fill the referencing objects. | 13167 // Fill the referencing objects. |
| 13176 HeapIterator heap_iterator2(heap); | 13168 HeapIterator heap_iterator2(heap); |
| 13177 count = DebugConstructedBy(&heap_iterator2, | 13169 count = DebugConstructedBy(&heap_iterator2, |
| 13178 constructor, | 13170 *constructor, |
| 13179 max_references, | 13171 max_references, |
| 13180 instances, | 13172 *instances, |
| 13181 count); | 13173 count); |
| 13182 | 13174 |
| 13183 // Return result as JS array. | 13175 // Return result as JS array. |
| 13184 Object* result; | 13176 Handle<JSFunction> array_function( |
| 13185 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( | |
| 13186 isolate->context()->native_context()->array_function()); | 13177 isolate->context()->native_context()->array_function()); |
| 13187 if (!maybe_result->ToObject(&result)) return maybe_result; | 13178 Handle<JSObject> result = isolate->factory()->NewJSObject(array_function); |
| 13188 } | 13179 isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances); |
| 13189 return JSArray::cast(result)->SetContent(instances); | 13180 return *result; |
| 13190 } | 13181 } |
| 13191 | 13182 |
| 13192 | 13183 |
| 13193 // Find the effective prototype object as returned by __proto__. | 13184 // Find the effective prototype object as returned by __proto__. |
| 13194 // args[0]: the object to find the prototype for. | 13185 // args[0]: the object to find the prototype for. |
| 13195 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { | 13186 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { |
| 13196 SealHandleScope shs(isolate); | 13187 SealHandleScope shs(isolate); |
| 13197 ASSERT(args.length() == 1); | 13188 ASSERT(args.length() == 1); |
| 13198 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 13189 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 13199 return GetPrototypeSkipHiddenPrototypes(isolate, obj); | 13190 return GetPrototypeSkipHiddenPrototypes(isolate, obj); |
| (...skipping 1843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15043 // Handle last resort GC and make sure to allow future allocations | 15034 // Handle last resort GC and make sure to allow future allocations |
| 15044 // to grow the heap without causing GCs (if possible). | 15035 // to grow the heap without causing GCs (if possible). |
| 15045 isolate->counters()->gc_last_resort_from_js()->Increment(); | 15036 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 15046 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 15037 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 15047 "Runtime::PerformGC"); | 15038 "Runtime::PerformGC"); |
| 15048 } | 15039 } |
| 15049 } | 15040 } |
| 15050 | 15041 |
| 15051 | 15042 |
| 15052 } } // namespace v8::internal | 15043 } } // namespace v8::internal |
| OLD | NEW |