OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1728 JSFunction::cast(constructor)->initial_map() == map) { | 1728 JSFunction::cast(constructor)->initial_map() == map) { |
1729 // If we still have the original map, set in-object properties directly. | 1729 // If we still have the original map, set in-object properties directly. |
1730 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); | 1730 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); |
1731 // TODO(lrn): Consider skipping write barrier on booleans as well. | 1731 // TODO(lrn): Consider skipping write barrier on booleans as well. |
1732 // Both true and false should be in oldspace at all times. | 1732 // Both true and false should be in oldspace at all times. |
1733 regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global); | 1733 regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global); |
1734 regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase); | 1734 regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase); |
1735 regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline); | 1735 regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline); |
1736 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, | 1736 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, |
1737 Smi::FromInt(0), | 1737 Smi::FromInt(0), |
1738 SKIP_WRITE_BARRIER); | 1738 SKIP_WRITE_BARRIER); // It's a Smi. |
1739 return regexp; | 1739 return regexp; |
1740 } | 1740 } |
1741 | 1741 |
1742 // Map has changed, so use generic, but slower, method. | 1742 // Map has changed, so use generic, but slower, method. |
1743 PropertyAttributes final = | 1743 PropertyAttributes final = |
1744 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); | 1744 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); |
1745 PropertyAttributes writable = | 1745 PropertyAttributes writable = |
1746 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | 1746 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
1747 Heap* heap = isolate->heap(); | 1747 Heap* heap = isolate->heap(); |
1748 MaybeObject* result; | 1748 MaybeObject* result; |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2142 int number_of_literals = fun->NumberOfLiterals(); | 2142 int number_of_literals = fun->NumberOfLiterals(); |
2143 Handle<FixedArray> literals = | 2143 Handle<FixedArray> literals = |
2144 isolate->factory()->NewFixedArray(number_of_literals, TENURED); | 2144 isolate->factory()->NewFixedArray(number_of_literals, TENURED); |
2145 if (number_of_literals > 0) { | 2145 if (number_of_literals > 0) { |
2146 // Insert the object, regexp and array functions in the literals | 2146 // Insert the object, regexp and array functions in the literals |
2147 // array prefix. These are the functions that will be used when | 2147 // array prefix. These are the functions that will be used when |
2148 // creating object, regexp and array literals. | 2148 // creating object, regexp and array literals. |
2149 literals->set(JSFunction::kLiteralGlobalContextIndex, | 2149 literals->set(JSFunction::kLiteralGlobalContextIndex, |
2150 context->global_context()); | 2150 context->global_context()); |
2151 } | 2151 } |
2152 // It's okay to skip the write barrier here because the literals | 2152 target->set_literals(*literals); |
2153 // are guaranteed to be in old space. | |
2154 target->set_literals(*literals, SKIP_WRITE_BARRIER); | |
2155 target->set_next_function_link(isolate->heap()->undefined_value()); | 2153 target->set_next_function_link(isolate->heap()->undefined_value()); |
2156 | 2154 |
2157 if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) { | 2155 if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) { |
2158 isolate->logger()->LogExistingFunction( | 2156 isolate->logger()->LogExistingFunction( |
2159 shared, Handle<Code>(shared->code())); | 2157 shared, Handle<Code>(shared->code())); |
2160 } | 2158 } |
2161 } | 2159 } |
2162 | 2160 |
2163 target->set_context(*context); | 2161 target->set_context(*context); |
2164 return *target; | 2162 return *target; |
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3145 // Shorten string and fill | 3143 // Shorten string and fill |
3146 int string_size = ResultSeqString::SizeFor(position); | 3144 int string_size = ResultSeqString::SizeFor(position); |
3147 int allocated_string_size = ResultSeqString::SizeFor(new_length); | 3145 int allocated_string_size = ResultSeqString::SizeFor(new_length); |
3148 int delta = allocated_string_size - string_size; | 3146 int delta = allocated_string_size - string_size; |
3149 | 3147 |
3150 answer->set_length(position); | 3148 answer->set_length(position); |
3151 if (delta == 0) return *answer; | 3149 if (delta == 0) return *answer; |
3152 | 3150 |
3153 Address end_of_string = answer->address() + string_size; | 3151 Address end_of_string = answer->address() + string_size; |
3154 isolate->heap()->CreateFillerObjectAt(end_of_string, delta); | 3152 isolate->heap()->CreateFillerObjectAt(end_of_string, delta); |
| 3153 if (Marking::IsBlack(Marking::MarkBitFrom(*answer))) { |
| 3154 MemoryChunk::IncrementLiveBytes(answer->address(), -delta); |
| 3155 } |
3155 | 3156 |
3156 return *answer; | 3157 return *answer; |
3157 } | 3158 } |
3158 | 3159 |
3159 | 3160 |
3160 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) { | 3161 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringReplaceRegExpWithString) { |
3161 ASSERT(args.length() == 4); | 3162 ASSERT(args.length() == 4); |
3162 | 3163 |
3163 CONVERT_CHECKED(String, subject, args[0]); | 3164 CONVERT_CHECKED(String, subject, args[0]); |
3164 if (!subject->IsFlat()) { | 3165 if (!subject->IsFlat()) { |
(...skipping 3015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6180 // not in the cache and fills the remainder with smi zeros. Returns | 6181 // not in the cache and fills the remainder with smi zeros. Returns |
6181 // the length of the successfully copied prefix. | 6182 // the length of the successfully copied prefix. |
6182 static int CopyCachedAsciiCharsToArray(Heap* heap, | 6183 static int CopyCachedAsciiCharsToArray(Heap* heap, |
6183 const char* chars, | 6184 const char* chars, |
6184 FixedArray* elements, | 6185 FixedArray* elements, |
6185 int length) { | 6186 int length) { |
6186 AssertNoAllocation no_gc; | 6187 AssertNoAllocation no_gc; |
6187 FixedArray* ascii_cache = heap->single_character_string_cache(); | 6188 FixedArray* ascii_cache = heap->single_character_string_cache(); |
6188 Object* undefined = heap->undefined_value(); | 6189 Object* undefined = heap->undefined_value(); |
6189 int i; | 6190 int i; |
| 6191 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
6190 for (i = 0; i < length; ++i) { | 6192 for (i = 0; i < length; ++i) { |
6191 Object* value = ascii_cache->get(chars[i]); | 6193 Object* value = ascii_cache->get(chars[i]); |
6192 if (value == undefined) break; | 6194 if (value == undefined) break; |
6193 ASSERT(!heap->InNewSpace(value)); | 6195 elements->set(i, value, mode); |
6194 elements->set(i, value, SKIP_WRITE_BARRIER); | |
6195 } | 6196 } |
6196 if (i < length) { | 6197 if (i < length) { |
6197 ASSERT(Smi::FromInt(0) == 0); | 6198 ASSERT(Smi::FromInt(0) == 0); |
6198 memset(elements->data_start() + i, 0, kPointerSize * (length - i)); | 6199 memset(elements->data_start() + i, 0, kPointerSize * (length - i)); |
6199 } | 6200 } |
6200 #ifdef DEBUG | 6201 #ifdef DEBUG |
6201 for (int j = 0; j < length; ++j) { | 6202 for (int j = 0; j < length; ++j) { |
6202 Object* element = elements->get(j); | 6203 Object* element = elements->get(j); |
6203 ASSERT(element == Smi::FromInt(0) || | 6204 ASSERT(element == Smi::FromInt(0) || |
6204 (element->IsString() && String::cast(element)->LooksValid())); | 6205 (element->IsString() && String::cast(element)->LooksValid())); |
(...skipping 5164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11369 // NOTE: This might require several heap iterations. If the SharedFunctionInfo | 11370 // NOTE: This might require several heap iterations. If the SharedFunctionInfo |
11370 // which is found is not compiled it is compiled and the heap is iterated | 11371 // which is found is not compiled it is compiled and the heap is iterated |
11371 // again as the compilation might create inner functions from the newly | 11372 // again as the compilation might create inner functions from the newly |
11372 // compiled function and the actual requested break point might be in one of | 11373 // compiled function and the actual requested break point might be in one of |
11373 // these functions. | 11374 // these functions. |
11374 bool done = false; | 11375 bool done = false; |
11375 // The current candidate for the source position: | 11376 // The current candidate for the source position: |
11376 int target_start_position = RelocInfo::kNoPosition; | 11377 int target_start_position = RelocInfo::kNoPosition; |
11377 Handle<SharedFunctionInfo> target; | 11378 Handle<SharedFunctionInfo> target; |
11378 while (!done) { | 11379 while (!done) { |
11379 HeapIterator iterator; | 11380 { // Extra scope for iterator and no-allocation. |
11380 for (HeapObject* obj = iterator.next(); | 11381 isolate->heap()->EnsureHeapIsIterable(); |
11381 obj != NULL; obj = iterator.next()) { | 11382 AssertNoAllocation no_alloc_during_heap_iteration; |
11382 if (obj->IsSharedFunctionInfo()) { | 11383 HeapIterator iterator; |
11383 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj)); | 11384 for (HeapObject* obj = iterator.next(); |
11384 if (shared->script() == *script) { | 11385 obj != NULL; obj = iterator.next()) { |
11385 // If the SharedFunctionInfo found has the requested script data and | 11386 if (obj->IsSharedFunctionInfo()) { |
11386 // contains the source position it is a candidate. | 11387 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj)); |
11387 int start_position = shared->function_token_position(); | 11388 if (shared->script() == *script) { |
11388 if (start_position == RelocInfo::kNoPosition) { | 11389 // If the SharedFunctionInfo found has the requested script data and |
11389 start_position = shared->start_position(); | 11390 // contains the source position it is a candidate. |
11390 } | 11391 int start_position = shared->function_token_position(); |
11391 if (start_position <= position && | 11392 if (start_position == RelocInfo::kNoPosition) { |
11392 position <= shared->end_position()) { | 11393 start_position = shared->start_position(); |
11393 // If there is no candidate or this function is within the current | 11394 } |
11394 // candidate this is the new candidate. | 11395 if (start_position <= position && |
11395 if (target.is_null()) { | 11396 position <= shared->end_position()) { |
11396 target_start_position = start_position; | 11397 // If there is no candidate or this function is within the current |
11397 target = shared; | 11398 // candidate this is the new candidate. |
11398 } else { | 11399 if (target.is_null()) { |
11399 if (target_start_position == start_position && | 11400 target_start_position = start_position; |
11400 shared->end_position() == target->end_position()) { | 11401 target = shared; |
11401 // If a top-level function contain only one function | 11402 } else { |
11402 // declartion the source for the top-level and the function is | 11403 if (target_start_position == start_position && |
11403 // the same. In that case prefer the non top-level function. | 11404 shared->end_position() == target->end_position()) { |
11404 if (!shared->is_toplevel()) { | 11405 // If a top-level function contain only one function |
| 11406 // declartion the source for the top-level and the |
| 11407 // function is the same. In that case prefer the non |
| 11408 // top-level function. |
| 11409 if (!shared->is_toplevel()) { |
| 11410 target_start_position = start_position; |
| 11411 target = shared; |
| 11412 } |
| 11413 } else if (target_start_position <= start_position && |
| 11414 shared->end_position() <= target->end_position()) { |
| 11415 // This containment check includes equality as a function |
| 11416 // inside a top-level function can share either start or end |
| 11417 // position with the top-level function. |
11405 target_start_position = start_position; | 11418 target_start_position = start_position; |
11406 target = shared; | 11419 target = shared; |
11407 } | 11420 } |
11408 } else if (target_start_position <= start_position && | |
11409 shared->end_position() <= target->end_position()) { | |
11410 // This containment check includes equality as a function inside | |
11411 // a top-level function can share either start or end position | |
11412 // with the top-level function. | |
11413 target_start_position = start_position; | |
11414 target = shared; | |
11415 } | 11421 } |
11416 } | 11422 } |
11417 } | 11423 } |
11418 } | 11424 } |
11419 } | 11425 } // End for loop. |
11420 } | 11426 } // End No allocation scope. |
11421 | 11427 |
11422 if (target.is_null()) { | 11428 if (target.is_null()) { |
11423 return isolate->heap()->undefined_value(); | 11429 return isolate->heap()->undefined_value(); |
11424 } | 11430 } |
11425 | 11431 |
11426 // If the candidate found is compiled we are done. NOTE: when lazy | 11432 // If the candidate found is compiled we are done. NOTE: when lazy |
11427 // compilation of inner functions is introduced some additional checking | 11433 // compilation of inner functions is introduced some additional checking |
11428 // needs to be done here to compile inner functions. | 11434 // needs to be done here to compile inner functions. |
11429 done = target->is_compiled(); | 11435 done = target->is_compiled(); |
11430 if (!done) { | 11436 if (!done) { |
11431 // If the candidate is not compiled compile it to reveal any inner | 11437 // If the candidate is not compiled compile it to reveal any inner |
11432 // functions which might contain the requested source position. | 11438 // functions which might contain the requested source position. |
11433 CompileLazyShared(target, KEEP_EXCEPTION); | 11439 CompileLazyShared(target, KEEP_EXCEPTION); |
11434 } | 11440 } |
11435 } | 11441 } // End while loop. |
11436 | 11442 |
11437 return *target; | 11443 return *target; |
11438 } | 11444 } |
11439 | 11445 |
11440 | 11446 |
11441 // Changes the state of a break point in a script and returns source position | 11447 // Changes the state of a break point in a script and returns source position |
11442 // where break point was set. NOTE: Regarding performance see the NOTE for | 11448 // where break point was set. NOTE: Regarding performance see the NOTE for |
11443 // GetScriptFromScriptData. | 11449 // GetScriptFromScriptData. |
11444 // args[0]: script to set break point in | 11450 // args[0]: script to set break point in |
11445 // args[1]: number: break source position (within the script source) | 11451 // args[1]: number: break source position (within the script source) |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11910 | 11916 |
11911 // Return result as a JS array. | 11917 // Return result as a JS array. |
11912 Handle<JSObject> result = | 11918 Handle<JSObject> result = |
11913 isolate->factory()->NewJSObject(isolate->array_function()); | 11919 isolate->factory()->NewJSObject(isolate->array_function()); |
11914 Handle<JSArray>::cast(result)->SetContent(*instances); | 11920 Handle<JSArray>::cast(result)->SetContent(*instances); |
11915 return *result; | 11921 return *result; |
11916 } | 11922 } |
11917 | 11923 |
11918 | 11924 |
11919 // Helper function used by Runtime_DebugReferencedBy below. | 11925 // Helper function used by Runtime_DebugReferencedBy below. |
11920 static int DebugReferencedBy(JSObject* target, | 11926 static int DebugReferencedBy(HeapIterator* iterator, |
| 11927 JSObject* target, |
11921 Object* instance_filter, int max_references, | 11928 Object* instance_filter, int max_references, |
11922 FixedArray* instances, int instances_size, | 11929 FixedArray* instances, int instances_size, |
11923 JSFunction* arguments_function) { | 11930 JSFunction* arguments_function) { |
11924 NoHandleAllocation ha; | 11931 NoHandleAllocation ha; |
11925 AssertNoAllocation no_alloc; | 11932 AssertNoAllocation no_alloc; |
11926 | 11933 |
11927 // Iterate the heap. | 11934 // Iterate the heap. |
11928 int count = 0; | 11935 int count = 0; |
11929 JSObject* last = NULL; | 11936 JSObject* last = NULL; |
11930 HeapIterator iterator; | |
11931 HeapObject* heap_obj = NULL; | 11937 HeapObject* heap_obj = NULL; |
11932 while (((heap_obj = iterator.next()) != NULL) && | 11938 while (((heap_obj = iterator->next()) != NULL) && |
11933 (max_references == 0 || count < max_references)) { | 11939 (max_references == 0 || count < max_references)) { |
11934 // Only look at all JSObjects. | 11940 // Only look at all JSObjects. |
11935 if (heap_obj->IsJSObject()) { | 11941 if (heap_obj->IsJSObject()) { |
11936 // Skip context extension objects and argument arrays as these are | 11942 // Skip context extension objects and argument arrays as these are |
11937 // checked in the context of functions using them. | 11943 // checked in the context of functions using them. |
11938 JSObject* obj = JSObject::cast(heap_obj); | 11944 JSObject* obj = JSObject::cast(heap_obj); |
11939 if (obj->IsJSContextExtensionObject() || | 11945 if (obj->IsJSContextExtensionObject() || |
11940 obj->map()->constructor() == arguments_function) { | 11946 obj->map()->constructor() == arguments_function) { |
11941 continue; | 11947 continue; |
11942 } | 11948 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11987 | 11993 |
11988 | 11994 |
11989 // Scan the heap for objects with direct references to an object | 11995 // Scan the heap for objects with direct references to an object |
11990 // args[0]: the object to find references to | 11996 // args[0]: the object to find references to |
11991 // args[1]: constructor function for instances to exclude (Mirror) | 11997 // args[1]: constructor function for instances to exclude (Mirror) |
11992 // args[2]: the the maximum number of objects to return | 11998 // args[2]: the the maximum number of objects to return |
11993 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) { | 11999 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) { |
11994 ASSERT(args.length() == 3); | 12000 ASSERT(args.length() == 3); |
11995 | 12001 |
11996 // First perform a full GC in order to avoid references from dead objects. | 12002 // First perform a full GC in order to avoid references from dead objects. |
11997 isolate->heap()->CollectAllGarbage(false); | 12003 isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask); |
| 12004 // The heap iterator reserves the right to do a GC to make the heap iterable. |
| 12005 // Due to the GC above we know it won't need to do that, but it seems cleaner |
| 12006 // to get the heap iterator constructed before we start having unprotected |
| 12007 // Object* locals that are not protected by handles. |
11998 | 12008 |
11999 // Check parameters. | 12009 // Check parameters. |
12000 CONVERT_CHECKED(JSObject, target, args[0]); | 12010 CONVERT_CHECKED(JSObject, target, args[0]); |
12001 Object* instance_filter = args[1]; | 12011 Object* instance_filter = args[1]; |
12002 RUNTIME_ASSERT(instance_filter->IsUndefined() || | 12012 RUNTIME_ASSERT(instance_filter->IsUndefined() || |
12003 instance_filter->IsJSObject()); | 12013 instance_filter->IsJSObject()); |
12004 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); | 12014 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); |
12005 RUNTIME_ASSERT(max_references >= 0); | 12015 RUNTIME_ASSERT(max_references >= 0); |
12006 | 12016 |
| 12017 |
12007 // Get the constructor function for context extension and arguments array. | 12018 // Get the constructor function for context extension and arguments array. |
12008 JSObject* arguments_boilerplate = | 12019 JSObject* arguments_boilerplate = |
12009 isolate->context()->global_context()->arguments_boilerplate(); | 12020 isolate->context()->global_context()->arguments_boilerplate(); |
12010 JSFunction* arguments_function = | 12021 JSFunction* arguments_function = |
12011 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 12022 JSFunction::cast(arguments_boilerplate->map()->constructor()); |
12012 | 12023 |
12013 // Get the number of referencing objects. | 12024 // Get the number of referencing objects. |
12014 int count; | 12025 int count; |
12015 count = DebugReferencedBy(target, instance_filter, max_references, | 12026 HeapIterator heap_iterator; |
| 12027 count = DebugReferencedBy(&heap_iterator, |
| 12028 target, instance_filter, max_references, |
12016 NULL, 0, arguments_function); | 12029 NULL, 0, arguments_function); |
12017 | 12030 |
12018 // Allocate an array to hold the result. | 12031 // Allocate an array to hold the result. |
12019 Object* object; | 12032 Object* object; |
12020 { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count); | 12033 { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count); |
12021 if (!maybe_object->ToObject(&object)) return maybe_object; | 12034 if (!maybe_object->ToObject(&object)) return maybe_object; |
12022 } | 12035 } |
12023 FixedArray* instances = FixedArray::cast(object); | 12036 FixedArray* instances = FixedArray::cast(object); |
12024 | 12037 |
12025 // Fill the referencing objects. | 12038 // Fill the referencing objects. |
12026 count = DebugReferencedBy(target, instance_filter, max_references, | 12039 // AllocateFixedArray above does not make the heap non-iterable. |
| 12040 ASSERT(HEAP->IsHeapIterable()); |
| 12041 HeapIterator heap_iterator2; |
| 12042 count = DebugReferencedBy(&heap_iterator2, |
| 12043 target, instance_filter, max_references, |
12027 instances, count, arguments_function); | 12044 instances, count, arguments_function); |
12028 | 12045 |
12029 // Return result as JS array. | 12046 // Return result as JS array. |
12030 Object* result; | 12047 Object* result; |
12031 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( | 12048 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
12032 isolate->context()->global_context()->array_function()); | 12049 isolate->context()->global_context()->array_function()); |
12033 if (!maybe_result->ToObject(&result)) return maybe_result; | 12050 if (!maybe_result->ToObject(&result)) return maybe_result; |
12034 } | 12051 } |
12035 JSArray::cast(result)->SetContent(instances); | 12052 JSArray::cast(result)->SetContent(instances); |
12036 return result; | 12053 return result; |
12037 } | 12054 } |
12038 | 12055 |
12039 | 12056 |
12040 // Helper function used by Runtime_DebugConstructedBy below. | 12057 // Helper function used by Runtime_DebugConstructedBy below. |
12041 static int DebugConstructedBy(JSFunction* constructor, int max_references, | 12058 static int DebugConstructedBy(HeapIterator* iterator, |
12042 FixedArray* instances, int instances_size) { | 12059 JSFunction* constructor, |
| 12060 int max_references, |
| 12061 FixedArray* instances, |
| 12062 int instances_size) { |
12043 AssertNoAllocation no_alloc; | 12063 AssertNoAllocation no_alloc; |
12044 | 12064 |
12045 // Iterate the heap. | 12065 // Iterate the heap. |
12046 int count = 0; | 12066 int count = 0; |
12047 HeapIterator iterator; | |
12048 HeapObject* heap_obj = NULL; | 12067 HeapObject* heap_obj = NULL; |
12049 while (((heap_obj = iterator.next()) != NULL) && | 12068 while (((heap_obj = iterator->next()) != NULL) && |
12050 (max_references == 0 || count < max_references)) { | 12069 (max_references == 0 || count < max_references)) { |
12051 // Only look at all JSObjects. | 12070 // Only look at all JSObjects. |
12052 if (heap_obj->IsJSObject()) { | 12071 if (heap_obj->IsJSObject()) { |
12053 JSObject* obj = JSObject::cast(heap_obj); | 12072 JSObject* obj = JSObject::cast(heap_obj); |
12054 if (obj->map()->constructor() == constructor) { | 12073 if (obj->map()->constructor() == constructor) { |
12055 // Valid reference found add to instance array if supplied an update | 12074 // Valid reference found add to instance array if supplied an update |
12056 // count. | 12075 // count. |
12057 if (instances != NULL && count < instances_size) { | 12076 if (instances != NULL && count < instances_size) { |
12058 instances->set(count, obj); | 12077 instances->set(count, obj); |
12059 } | 12078 } |
12060 count++; | 12079 count++; |
12061 } | 12080 } |
12062 } | 12081 } |
12063 } | 12082 } |
12064 | 12083 |
12065 // Return the number of referencing objects found. | 12084 // Return the number of referencing objects found. |
12066 return count; | 12085 return count; |
12067 } | 12086 } |
12068 | 12087 |
12069 | 12088 |
12070 // Scan the heap for objects constructed by a specific function. | 12089 // Scan the heap for objects constructed by a specific function. |
12071 // args[0]: the constructor to find instances of | 12090 // args[0]: the constructor to find instances of |
12072 // args[1]: the the maximum number of objects to return | 12091 // args[1]: the the maximum number of objects to return |
12073 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) { | 12092 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) { |
12074 ASSERT(args.length() == 2); | 12093 ASSERT(args.length() == 2); |
12075 | 12094 |
12076 // First perform a full GC in order to avoid dead objects. | 12095 // First perform a full GC in order to avoid dead objects. |
12077 isolate->heap()->CollectAllGarbage(false); | 12096 isolate->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask); |
12078 | 12097 |
12079 // Check parameters. | 12098 // Check parameters. |
12080 CONVERT_CHECKED(JSFunction, constructor, args[0]); | 12099 CONVERT_CHECKED(JSFunction, constructor, args[0]); |
12081 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); | 12100 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); |
12082 RUNTIME_ASSERT(max_references >= 0); | 12101 RUNTIME_ASSERT(max_references >= 0); |
12083 | 12102 |
12084 // Get the number of referencing objects. | 12103 // Get the number of referencing objects. |
12085 int count; | 12104 int count; |
12086 count = DebugConstructedBy(constructor, max_references, NULL, 0); | 12105 HeapIterator heap_iterator; |
| 12106 count = DebugConstructedBy(&heap_iterator, |
| 12107 constructor, |
| 12108 max_references, |
| 12109 NULL, |
| 12110 0); |
12087 | 12111 |
12088 // Allocate an array to hold the result. | 12112 // Allocate an array to hold the result. |
12089 Object* object; | 12113 Object* object; |
12090 { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count); | 12114 { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count); |
12091 if (!maybe_object->ToObject(&object)) return maybe_object; | 12115 if (!maybe_object->ToObject(&object)) return maybe_object; |
12092 } | 12116 } |
12093 FixedArray* instances = FixedArray::cast(object); | 12117 FixedArray* instances = FixedArray::cast(object); |
12094 | 12118 |
| 12119 ASSERT(HEAP->IsHeapIterable()); |
12095 // Fill the referencing objects. | 12120 // Fill the referencing objects. |
12096 count = DebugConstructedBy(constructor, max_references, instances, count); | 12121 HeapIterator heap_iterator2; |
| 12122 count = DebugConstructedBy(&heap_iterator2, |
| 12123 constructor, |
| 12124 max_references, |
| 12125 instances, |
| 12126 count); |
12097 | 12127 |
12098 // Return result as JS array. | 12128 // Return result as JS array. |
12099 Object* result; | 12129 Object* result; |
12100 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( | 12130 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
12101 isolate->context()->global_context()->array_function()); | 12131 isolate->context()->global_context()->array_function()); |
12102 if (!maybe_result->ToObject(&result)) return maybe_result; | 12132 if (!maybe_result->ToObject(&result)) return maybe_result; |
12103 } | 12133 } |
12104 JSArray::cast(result)->SetContent(instances); | 12134 JSArray::cast(result)->SetContent(instances); |
12105 return result; | 12135 return result; |
12106 } | 12136 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12159 | 12189 |
12160 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) { | 12190 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) { |
12161 NoHandleAllocation ha; | 12191 NoHandleAllocation ha; |
12162 ASSERT(args.length() == 1); | 12192 ASSERT(args.length() == 1); |
12163 | 12193 |
12164 CONVERT_CHECKED(JSFunction, f, args[0]); | 12194 CONVERT_CHECKED(JSFunction, f, args[0]); |
12165 return f->shared()->inferred_name(); | 12195 return f->shared()->inferred_name(); |
12166 } | 12196 } |
12167 | 12197 |
12168 | 12198 |
12169 static int FindSharedFunctionInfosForScript(Script* script, | 12199 static int FindSharedFunctionInfosForScript(HeapIterator* iterator, |
| 12200 Script* script, |
12170 FixedArray* buffer) { | 12201 FixedArray* buffer) { |
12171 AssertNoAllocation no_allocations; | 12202 AssertNoAllocation no_allocations; |
12172 | |
12173 int counter = 0; | 12203 int counter = 0; |
12174 int buffer_size = buffer->length(); | 12204 int buffer_size = buffer->length(); |
12175 HeapIterator iterator; | 12205 for (HeapObject* obj = iterator->next(); |
12176 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 12206 obj != NULL; |
| 12207 obj = iterator->next()) { |
12177 ASSERT(obj != NULL); | 12208 ASSERT(obj != NULL); |
12178 if (!obj->IsSharedFunctionInfo()) { | 12209 if (!obj->IsSharedFunctionInfo()) { |
12179 continue; | 12210 continue; |
12180 } | 12211 } |
12181 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | 12212 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
12182 if (shared->script() != script) { | 12213 if (shared->script() != script) { |
12183 continue; | 12214 continue; |
12184 } | 12215 } |
12185 if (counter < buffer_size) { | 12216 if (counter < buffer_size) { |
12186 buffer->set(counter, shared); | 12217 buffer->set(counter, shared); |
12187 } | 12218 } |
12188 counter++; | 12219 counter++; |
12189 } | 12220 } |
12190 return counter; | 12221 return counter; |
12191 } | 12222 } |
12192 | 12223 |
12193 // For a script finds all SharedFunctionInfo's in the heap that points | 12224 // For a script finds all SharedFunctionInfo's in the heap that points |
12194 // to this script. Returns JSArray of SharedFunctionInfo wrapped | 12225 // to this script. Returns JSArray of SharedFunctionInfo wrapped |
12195 // in OpaqueReferences. | 12226 // in OpaqueReferences. |
12196 RUNTIME_FUNCTION(MaybeObject*, | 12227 RUNTIME_FUNCTION(MaybeObject*, |
12197 Runtime_LiveEditFindSharedFunctionInfosForScript) { | 12228 Runtime_LiveEditFindSharedFunctionInfosForScript) { |
12198 ASSERT(args.length() == 1); | 12229 ASSERT(args.length() == 1); |
12199 HandleScope scope(isolate); | 12230 HandleScope scope(isolate); |
12200 CONVERT_CHECKED(JSValue, script_value, args[0]); | 12231 CONVERT_CHECKED(JSValue, script_value, args[0]); |
12201 | 12232 |
| 12233 |
12202 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); | 12234 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); |
12203 | 12235 |
12204 const int kBufferSize = 32; | 12236 const int kBufferSize = 32; |
12205 | 12237 |
12206 Handle<FixedArray> array; | 12238 Handle<FixedArray> array; |
12207 array = isolate->factory()->NewFixedArray(kBufferSize); | 12239 array = isolate->factory()->NewFixedArray(kBufferSize); |
12208 int number = FindSharedFunctionInfosForScript(*script, *array); | 12240 int number; |
| 12241 { |
| 12242 isolate->heap()->EnsureHeapIsIterable(); |
| 12243 AssertNoAllocation no_allocations; |
| 12244 HeapIterator heap_iterator; |
| 12245 Script* scr = *script; |
| 12246 FixedArray* arr = *array; |
| 12247 number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr); |
| 12248 } |
12209 if (number > kBufferSize) { | 12249 if (number > kBufferSize) { |
12210 array = isolate->factory()->NewFixedArray(number); | 12250 array = isolate->factory()->NewFixedArray(number); |
12211 FindSharedFunctionInfosForScript(*script, *array); | 12251 isolate->heap()->EnsureHeapIsIterable(); |
| 12252 AssertNoAllocation no_allocations; |
| 12253 HeapIterator heap_iterator; |
| 12254 Script* scr = *script; |
| 12255 FixedArray* arr = *array; |
| 12256 FindSharedFunctionInfosForScript(&heap_iterator, scr, arr); |
12212 } | 12257 } |
12213 | 12258 |
12214 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array); | 12259 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array); |
12215 result->set_length(Smi::FromInt(number)); | 12260 result->set_length(Smi::FromInt(number)); |
12216 | 12261 |
12217 LiveEdit::WrapSharedFunctionInfos(result); | 12262 LiveEdit::WrapSharedFunctionInfos(result); |
12218 | 12263 |
12219 return *result; | 12264 return *result; |
12220 } | 12265 } |
12221 | 12266 |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12682 // heap traversal to find the function generated for the source position | 12727 // heap traversal to find the function generated for the source position |
12683 // for the requested break point. For lazily compiled functions several heap | 12728 // for the requested break point. For lazily compiled functions several heap |
12684 // traversals might be required rendering this operation as a rather slow | 12729 // traversals might be required rendering this operation as a rather slow |
12685 // operation. However for setting break points which is normally done through | 12730 // operation. However for setting break points which is normally done through |
12686 // some kind of user interaction the performance is not crucial. | 12731 // some kind of user interaction the performance is not crucial. |
12687 static Handle<Object> Runtime_GetScriptFromScriptName( | 12732 static Handle<Object> Runtime_GetScriptFromScriptName( |
12688 Handle<String> script_name) { | 12733 Handle<String> script_name) { |
12689 // Scan the heap for Script objects to find the script with the requested | 12734 // Scan the heap for Script objects to find the script with the requested |
12690 // script data. | 12735 // script data. |
12691 Handle<Script> script; | 12736 Handle<Script> script; |
| 12737 script_name->GetHeap()->EnsureHeapIsIterable(); |
| 12738 AssertNoAllocation no_allocation_during_heap_iteration; |
12692 HeapIterator iterator; | 12739 HeapIterator iterator; |
12693 HeapObject* obj = NULL; | 12740 HeapObject* obj = NULL; |
12694 while (script.is_null() && ((obj = iterator.next()) != NULL)) { | 12741 while (script.is_null() && ((obj = iterator.next()) != NULL)) { |
12695 // If a script is found check if it has the script data requested. | 12742 // If a script is found check if it has the script data requested. |
12696 if (obj->IsScript()) { | 12743 if (obj->IsScript()) { |
12697 if (Script::cast(obj)->name()->IsString()) { | 12744 if (Script::cast(obj)->name()->IsString()) { |
12698 if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) { | 12745 if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) { |
12699 script = Handle<Script>(Script::cast(obj)); | 12746 script = Handle<Script>(Script::cast(obj)); |
12700 } | 12747 } |
12701 } | 12748 } |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13133 | 13180 |
13134 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 13181 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
13135 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 13182 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
13136 } | 13183 } |
13137 | 13184 |
13138 | 13185 |
13139 void Runtime::PerformGC(Object* result) { | 13186 void Runtime::PerformGC(Object* result) { |
13140 Isolate* isolate = Isolate::Current(); | 13187 Isolate* isolate = Isolate::Current(); |
13141 Failure* failure = Failure::cast(result); | 13188 Failure* failure = Failure::cast(result); |
13142 if (failure->IsRetryAfterGC()) { | 13189 if (failure->IsRetryAfterGC()) { |
| 13190 if (isolate->heap()->new_space()->AddFreshPage()) { |
| 13191 return; |
| 13192 } |
13143 // Try to do a garbage collection; ignore it if it fails. The C | 13193 // Try to do a garbage collection; ignore it if it fails. The C |
13144 // entry stub will throw an out-of-memory exception in that case. | 13194 // entry stub will throw an out-of-memory exception in that case. |
13145 isolate->heap()->CollectGarbage(failure->allocation_space()); | 13195 isolate->heap()->CollectGarbage(failure->allocation_space()); |
13146 } else { | 13196 } else { |
13147 // Handle last resort GC and make sure to allow future allocations | 13197 // Handle last resort GC and make sure to allow future allocations |
13148 // to grow the heap without causing GCs (if possible). | 13198 // to grow the heap without causing GCs (if possible). |
13149 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13199 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13150 isolate->heap()->CollectAllGarbage(false); | 13200 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
13151 } | 13201 } |
13152 } | 13202 } |
13153 | 13203 |
13154 | 13204 |
13155 } } // namespace v8::internal | 13205 } } // namespace v8::internal |
OLD | NEW |