| 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 20 matching lines...) Expand all Loading... |
| 31 #include "api.h" | 31 #include "api.h" |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "codegen-inl.h" | 33 #include "codegen-inl.h" |
| 34 #include "compilation-cache.h" | 34 #include "compilation-cache.h" |
| 35 #include "debug.h" | 35 #include "debug.h" |
| 36 #include "heap-profiler.h" | 36 #include "heap-profiler.h" |
| 37 #include "global-handles.h" | 37 #include "global-handles.h" |
| 38 #include "mark-compact.h" | 38 #include "mark-compact.h" |
| 39 #include "natives.h" | 39 #include "natives.h" |
| 40 #include "objects-visiting.h" | 40 #include "objects-visiting.h" |
| 41 #include "runtime-profiler.h" |
| 41 #include "scanner-base.h" | 42 #include "scanner-base.h" |
| 42 #include "scopeinfo.h" | 43 #include "scopeinfo.h" |
| 43 #include "snapshot.h" | 44 #include "snapshot.h" |
| 44 #include "v8threads.h" | 45 #include "v8threads.h" |
| 46 #include "vm-state-inl.h" |
| 45 #if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP | 47 #if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP |
| 46 #include "regexp-macro-assembler.h" | 48 #include "regexp-macro-assembler.h" |
| 47 #include "arm/regexp-macro-assembler-arm.h" | 49 #include "arm/regexp-macro-assembler-arm.h" |
| 48 #endif | 50 #endif |
| 49 | 51 |
| 50 namespace v8 { | 52 namespace v8 { |
| 51 namespace internal { | 53 namespace internal { |
| 52 | 54 |
| 53 | 55 |
| 54 static const intptr_t kMinimumPromotionLimit = 2 * MB; | 56 static const intptr_t kMinimumPromotionLimit = 2 * MB; |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 } | 832 } |
| 831 | 833 |
| 832 | 834 |
| 833 void Heap::MarkCompactPrologue(bool is_compacting) { | 835 void Heap::MarkCompactPrologue(bool is_compacting) { |
| 834 // At any old GC clear the keyed lookup cache to enable collection of unused | 836 // At any old GC clear the keyed lookup cache to enable collection of unused |
| 835 // maps. | 837 // maps. |
| 836 isolate_->keyed_lookup_cache()->Clear(); | 838 isolate_->keyed_lookup_cache()->Clear(); |
| 837 isolate_->context_slot_cache()->Clear(); | 839 isolate_->context_slot_cache()->Clear(); |
| 838 isolate_->descriptor_lookup_cache()->Clear(); | 840 isolate_->descriptor_lookup_cache()->Clear(); |
| 839 | 841 |
| 842 isolate_->runtime_profiler()->MarkCompactPrologue(is_compacting); |
| 843 |
| 840 isolate_->compilation_cache()->MarkCompactPrologue(); | 844 isolate_->compilation_cache()->MarkCompactPrologue(); |
| 841 | 845 |
| 842 CompletelyClearInstanceofCache(); | 846 CompletelyClearInstanceofCache(); |
| 843 | 847 |
| 844 if (is_compacting) FlushNumberStringCache(); | 848 if (is_compacting) FlushNumberStringCache(); |
| 845 | 849 |
| 846 ClearNormalizedMapCaches(); | 850 ClearNormalizedMapCaches(); |
| 847 } | 851 } |
| 848 | 852 |
| 849 | 853 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 Address value_address = | 1013 Address value_address = |
| 1010 reinterpret_cast<Address>(cell) + | 1014 reinterpret_cast<Address>(cell) + |
| 1011 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); | 1015 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); |
| 1012 scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); | 1016 scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); |
| 1013 } | 1017 } |
| 1014 } | 1018 } |
| 1015 | 1019 |
| 1016 // Scavenge object reachable from the global contexts list directly. | 1020 // Scavenge object reachable from the global contexts list directly. |
| 1017 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); | 1021 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); |
| 1018 | 1022 |
| 1023 // Scavenge objects reachable from the runtime-profiler sampler |
| 1024 // window directly. |
| 1025 RuntimeProfiler* runtime_profiler = isolate_->runtime_profiler(); |
| 1026 Object** sampler_window_address = runtime_profiler->SamplerWindowAddress(); |
| 1027 int sampler_window_size = runtime_profiler->SamplerWindowSize(); |
| 1028 scavenge_visitor.VisitPointers( |
| 1029 sampler_window_address, |
| 1030 sampler_window_address + sampler_window_size); |
| 1031 |
| 1019 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1032 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1020 | 1033 |
| 1021 UpdateNewSpaceReferencesInExternalStringTable( | 1034 UpdateNewSpaceReferencesInExternalStringTable( |
| 1022 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1035 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
| 1023 | 1036 |
| 1024 ASSERT(new_space_front == new_space_.top()); | 1037 ASSERT(new_space_front == new_space_.top()); |
| 1025 | 1038 |
| 1026 is_safe_to_read_maps_ = true; | 1039 is_safe_to_read_maps_ = true; |
| 1027 | 1040 |
| 1028 // Set age mark. | 1041 // Set age mark. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1079 // String got promoted. Move it to the old string list. | 1092 // String got promoted. Move it to the old string list. |
| 1080 external_string_table_.AddOldString(target); | 1093 external_string_table_.AddOldString(target); |
| 1081 } | 1094 } |
| 1082 } | 1095 } |
| 1083 | 1096 |
| 1084 ASSERT(last <= end); | 1097 ASSERT(last <= end); |
| 1085 external_string_table_.ShrinkNewStrings(static_cast<int>(last - start)); | 1098 external_string_table_.ShrinkNewStrings(static_cast<int>(last - start)); |
| 1086 } | 1099 } |
| 1087 | 1100 |
| 1088 | 1101 |
| 1102 static Object* ProcessFunctionWeakReferences(Heap* heap, |
| 1103 Object* function, |
| 1104 WeakObjectRetainer* retainer) { |
| 1105 Object* head = heap->undefined_value(); |
| 1106 JSFunction* tail = NULL; |
| 1107 Object* candidate = function; |
| 1108 while (candidate != heap->undefined_value()) { |
| 1109 // Check whether to keep the candidate in the list. |
| 1110 JSFunction* candidate_function = reinterpret_cast<JSFunction*>(candidate); |
| 1111 Object* retain = retainer->RetainAs(candidate); |
| 1112 if (retain != NULL) { |
| 1113 if (head == heap->undefined_value()) { |
| 1114 // First element in the list. |
| 1115 head = candidate_function; |
| 1116 } else { |
| 1117 // Subsequent elements in the list. |
| 1118 ASSERT(tail != NULL); |
| 1119 tail->set_next_function_link(candidate_function); |
| 1120 } |
| 1121 // Retained function is new tail. |
| 1122 tail = candidate_function; |
| 1123 } |
| 1124 // Move to next element in the list. |
| 1125 candidate = candidate_function->next_function_link(); |
| 1126 } |
| 1127 |
| 1128 // Terminate the list if there is one or more elements. |
| 1129 if (tail != NULL) { |
| 1130 tail->set_next_function_link(heap->undefined_value()); |
| 1131 } |
| 1132 |
| 1133 return head; |
| 1134 } |
| 1135 |
| 1136 |
| 1089 void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { | 1137 void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { |
| 1090 Object* head = undefined_value(); | 1138 Object* head = undefined_value(); |
| 1091 Context* tail = NULL; | 1139 Context* tail = NULL; |
| 1092 Object* candidate = global_contexts_list_; | 1140 Object* candidate = global_contexts_list_; |
| 1093 while (candidate != undefined_value()) { | 1141 while (candidate != undefined_value()) { |
| 1094 // Check whether to keep the candidate in the list. | 1142 // Check whether to keep the candidate in the list. |
| 1095 Context* candidate_context = reinterpret_cast<Context*>(candidate); | 1143 Context* candidate_context = reinterpret_cast<Context*>(candidate); |
| 1096 Object* retain = retainer->RetainAs(candidate); | 1144 Object* retain = retainer->RetainAs(candidate); |
| 1097 if (retain != NULL) { | 1145 if (retain != NULL) { |
| 1098 if (head == undefined_value()) { | 1146 if (head == undefined_value()) { |
| 1099 // First element in the list. | 1147 // First element in the list. |
| 1100 head = candidate_context; | 1148 head = candidate_context; |
| 1101 } else { | 1149 } else { |
| 1102 // Subsequent elements in the list. | 1150 // Subsequent elements in the list. |
| 1103 ASSERT(tail != NULL); | 1151 ASSERT(tail != NULL); |
| 1104 tail->set_unchecked(this, | 1152 tail->set_unchecked(this, |
| 1105 Context::NEXT_CONTEXT_LINK, | 1153 Context::NEXT_CONTEXT_LINK, |
| 1106 candidate_context, | 1154 candidate_context, |
| 1107 UPDATE_WRITE_BARRIER); | 1155 UPDATE_WRITE_BARRIER); |
| 1108 } | 1156 } |
| 1109 // Retained context is new tail. | 1157 // Retained context is new tail. |
| 1110 tail = candidate_context; | 1158 tail = candidate_context; |
| 1159 |
| 1160 // Process the weak list of optimized functions for the context. |
| 1161 Object* function_list_head = |
| 1162 ProcessFunctionWeakReferences( |
| 1163 this, |
| 1164 candidate_context->get(Context::OPTIMIZED_FUNCTIONS_LIST), |
| 1165 retainer); |
| 1166 candidate_context->set_unchecked(this, |
| 1167 Context::OPTIMIZED_FUNCTIONS_LIST, |
| 1168 function_list_head, |
| 1169 UPDATE_WRITE_BARRIER); |
| 1111 } | 1170 } |
| 1112 // Move to next element in the list. | 1171 // Move to next element in the list. |
| 1113 candidate = candidate_context->get(Context::NEXT_CONTEXT_LINK); | 1172 candidate = candidate_context->get(Context::NEXT_CONTEXT_LINK); |
| 1114 } | 1173 } |
| 1115 | 1174 |
| 1116 // Terminate the list if there is one or more elements. | 1175 // Terminate the list if there is one or more elements. |
| 1117 if (tail != NULL) { | 1176 if (tail != NULL) { |
| 1118 tail->set_unchecked(this, | 1177 tail->set_unchecked(this, |
| 1119 Context::NEXT_CONTEXT_LINK, | 1178 Context::NEXT_CONTEXT_LINK, |
| 1120 Heap::undefined_value(), | 1179 Heap::undefined_value(), |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1618 } | 1677 } |
| 1619 set_undetectable_ascii_string_map(Map::cast(obj)); | 1678 set_undetectable_ascii_string_map(Map::cast(obj)); |
| 1620 Map::cast(obj)->set_is_undetectable(); | 1679 Map::cast(obj)->set_is_undetectable(); |
| 1621 | 1680 |
| 1622 { MaybeObject* maybe_obj = | 1681 { MaybeObject* maybe_obj = |
| 1623 AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel); | 1682 AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel); |
| 1624 if (!maybe_obj->ToObject(&obj)) return false; | 1683 if (!maybe_obj->ToObject(&obj)) return false; |
| 1625 } | 1684 } |
| 1626 set_byte_array_map(Map::cast(obj)); | 1685 set_byte_array_map(Map::cast(obj)); |
| 1627 | 1686 |
| 1687 { MaybeObject* maybe_obj = AllocateByteArray(0, TENURED); |
| 1688 if (!maybe_obj->ToObject(&obj)) return false; |
| 1689 } |
| 1690 set_empty_byte_array(ByteArray::cast(obj)); |
| 1691 |
| 1628 { MaybeObject* maybe_obj = | 1692 { MaybeObject* maybe_obj = |
| 1629 AllocateMap(PIXEL_ARRAY_TYPE, PixelArray::kAlignedSize); | 1693 AllocateMap(PIXEL_ARRAY_TYPE, PixelArray::kAlignedSize); |
| 1630 if (!maybe_obj->ToObject(&obj)) return false; | 1694 if (!maybe_obj->ToObject(&obj)) return false; |
| 1631 } | 1695 } |
| 1632 set_pixel_array_map(Map::cast(obj)); | 1696 set_pixel_array_map(Map::cast(obj)); |
| 1633 | 1697 |
| 1634 { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_BYTE_ARRAY_TYPE, | 1698 { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_BYTE_ARRAY_TYPE, |
| 1635 ExternalArray::kAlignedSize); | 1699 ExternalArray::kAlignedSize); |
| 1636 if (!maybe_obj->ToObject(&obj)) return false; | 1700 if (!maybe_obj->ToObject(&obj)) return false; |
| 1637 } | 1701 } |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2226 share->set_expected_nof_properties(0); | 2290 share->set_expected_nof_properties(0); |
| 2227 share->set_length(0); | 2291 share->set_length(0); |
| 2228 share->set_formal_parameter_count(0); | 2292 share->set_formal_parameter_count(0); |
| 2229 share->set_instance_class_name(Object_symbol()); | 2293 share->set_instance_class_name(Object_symbol()); |
| 2230 share->set_function_data(undefined_value()); | 2294 share->set_function_data(undefined_value()); |
| 2231 share->set_script(undefined_value()); | 2295 share->set_script(undefined_value()); |
| 2232 share->set_start_position_and_type(0); | 2296 share->set_start_position_and_type(0); |
| 2233 share->set_debug_info(undefined_value()); | 2297 share->set_debug_info(undefined_value()); |
| 2234 share->set_inferred_name(empty_string()); | 2298 share->set_inferred_name(empty_string()); |
| 2235 share->set_compiler_hints(0); | 2299 share->set_compiler_hints(0); |
| 2300 share->set_deopt_counter(Smi::FromInt(FLAG_deopt_every_n_times)); |
| 2236 share->set_initial_map(undefined_value()); | 2301 share->set_initial_map(undefined_value()); |
| 2237 share->set_this_property_assignments_count(0); | 2302 share->set_this_property_assignments_count(0); |
| 2238 share->set_this_property_assignments(undefined_value()); | 2303 share->set_this_property_assignments(undefined_value()); |
| 2304 share->set_opt_count(0); |
| 2239 share->set_num_literals(0); | 2305 share->set_num_literals(0); |
| 2240 share->set_end_position(0); | 2306 share->set_end_position(0); |
| 2241 share->set_function_token_position(0); | 2307 share->set_function_token_position(0); |
| 2242 return result; | 2308 return result; |
| 2243 } | 2309 } |
| 2244 | 2310 |
| 2245 | 2311 |
| 2246 // Returns true for a character in a range. Both limits are inclusive. | 2312 // Returns true for a character in a range. Both limits are inclusive. |
| 2247 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { | 2313 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { |
| 2248 // This makes uses of the the unsigned wraparound. | 2314 // This makes uses of the the unsigned wraparound. |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2649 if (!maybe_result->ToObject(&result)) return maybe_result; | 2715 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2650 | 2716 |
| 2651 // Initialize the object | 2717 // Initialize the object |
| 2652 HeapObject::cast(result)->set_map(code_map()); | 2718 HeapObject::cast(result)->set_map(code_map()); |
| 2653 Code* code = Code::cast(result); | 2719 Code* code = Code::cast(result); |
| 2654 ASSERT(!isolate_->code_range()->exists() || | 2720 ASSERT(!isolate_->code_range()->exists() || |
| 2655 isolate_->code_range()->contains(code->address())); | 2721 isolate_->code_range()->contains(code->address())); |
| 2656 code->set_instruction_size(desc.instr_size); | 2722 code->set_instruction_size(desc.instr_size); |
| 2657 code->set_relocation_info(ByteArray::cast(reloc_info)); | 2723 code->set_relocation_info(ByteArray::cast(reloc_info)); |
| 2658 code->set_flags(flags); | 2724 code->set_flags(flags); |
| 2725 code->set_deoptimization_data(empty_fixed_array()); |
| 2659 // Allow self references to created code object by patching the handle to | 2726 // Allow self references to created code object by patching the handle to |
| 2660 // point to the newly allocated Code object. | 2727 // point to the newly allocated Code object. |
| 2661 if (!self_reference.is_null()) { | 2728 if (!self_reference.is_null()) { |
| 2662 *(self_reference.location()) = code; | 2729 *(self_reference.location()) = code; |
| 2663 } | 2730 } |
| 2664 // Migrate generated code. | 2731 // Migrate generated code. |
| 2665 // The generated code can contain Object** values (typically from handles) | 2732 // The generated code can contain Object** values (typically from handles) |
| 2666 // that are dereferenced during the copy to point directly to the actual heap | 2733 // that are dereferenced during the copy to point directly to the actual heap |
| 2667 // objects. These pointers can include references to the code object itself, | 2734 // objects. These pointers can include references to the code object itself, |
| 2668 // through the self_reference parameter. | 2735 // through the self_reference parameter. |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2779 SharedFunctionInfo* shared, | 2846 SharedFunctionInfo* shared, |
| 2780 Object* prototype) { | 2847 Object* prototype) { |
| 2781 ASSERT(!prototype->IsMap()); | 2848 ASSERT(!prototype->IsMap()); |
| 2782 function->initialize_properties(); | 2849 function->initialize_properties(); |
| 2783 function->initialize_elements(); | 2850 function->initialize_elements(); |
| 2784 function->set_shared(shared); | 2851 function->set_shared(shared); |
| 2785 function->set_code(shared->code()); | 2852 function->set_code(shared->code()); |
| 2786 function->set_prototype_or_initial_map(prototype); | 2853 function->set_prototype_or_initial_map(prototype); |
| 2787 function->set_context(undefined_value()); | 2854 function->set_context(undefined_value()); |
| 2788 function->set_literals(empty_fixed_array()); | 2855 function->set_literals(empty_fixed_array()); |
| 2856 function->set_next_function_link(undefined_value()); |
| 2789 return function; | 2857 return function; |
| 2790 } | 2858 } |
| 2791 | 2859 |
| 2792 | 2860 |
| 2793 MaybeObject* Heap::AllocateFunctionPrototype(JSFunction* function) { | 2861 MaybeObject* Heap::AllocateFunctionPrototype(JSFunction* function) { |
| 2794 // Allocate the prototype. Make sure to use the object function | 2862 // Allocate the prototype. Make sure to use the object function |
| 2795 // from the function's context, since the function can be from a | 2863 // from the function's context, since the function can be from a |
| 2796 // different context. | 2864 // different context. |
| 2797 JSFunction* object_function = | 2865 JSFunction* object_function = |
| 2798 function->context()->global_context()->object_function(); | 2866 function->context()->global_context()->object_function(); |
| (...skipping 2634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5433 } | 5501 } |
| 5434 | 5502 |
| 5435 | 5503 |
| 5436 void ExternalStringTable::TearDown() { | 5504 void ExternalStringTable::TearDown() { |
| 5437 new_space_strings_.Free(); | 5505 new_space_strings_.Free(); |
| 5438 old_space_strings_.Free(); | 5506 old_space_strings_.Free(); |
| 5439 } | 5507 } |
| 5440 | 5508 |
| 5441 | 5509 |
| 5442 } } // namespace v8::internal | 5510 } } // namespace v8::internal |
| OLD | NEW |