OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "accessors.h" | 7 #include "accessors.h" |
8 #include "allocation-site-scopes.h" | 8 #include "allocation-site-scopes.h" |
9 #include "api.h" | 9 #include "api.h" |
10 #include "arguments.h" | 10 #include "arguments.h" |
(...skipping 10188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10199 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); | 10199 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); |
10200 } | 10200 } |
10201 | 10201 |
10202 // Now some logic for the maps of the objects that are created by using this | 10202 // Now some logic for the maps of the objects that are created by using this |
10203 // function as a constructor. | 10203 // function as a constructor. |
10204 if (function->has_initial_map()) { | 10204 if (function->has_initial_map()) { |
10205 // If the function has allocated the initial map replace it with a | 10205 // If the function has allocated the initial map replace it with a |
10206 // copy containing the new prototype. Also complete any in-object | 10206 // copy containing the new prototype. Also complete any in-object |
10207 // slack tracking that is in progress at this point because it is | 10207 // slack tracking that is in progress at this point because it is |
10208 // still tracking the old copy. | 10208 // still tracking the old copy. |
10209 if (function->shared()->IsInobjectSlackTrackingInProgress()) { | 10209 if (function->IsInobjectSlackTrackingInProgress()) { |
10210 function->shared()->CompleteInobjectSlackTracking(); | 10210 function->CompleteInobjectSlackTracking(); |
10211 } | 10211 } |
10212 Handle<Map> new_map = Map::Copy(handle(function->initial_map())); | 10212 Handle<Map> new_map = Map::Copy(handle(function->initial_map())); |
10213 new_map->set_prototype(*value); | 10213 new_map->set_prototype(*value); |
10214 | 10214 |
10215 // If the function is used as the global Array function, cache the | 10215 // If the function is used as the global Array function, cache the |
10216 // initial map (and transitioned versions) in the native context. | 10216 // initial map (and transitioned versions) in the native context. |
10217 Context* native_context = function->context()->native_context(); | 10217 Context* native_context = function->context()->native_context(); |
10218 Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX); | 10218 Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX); |
10219 if (array_function->IsJSFunction() && | 10219 if (array_function->IsJSFunction() && |
10220 *function == JSFunction::cast(array_function)) { | 10220 *function == JSFunction::cast(array_function)) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10309 if (function->has_instance_prototype()) { | 10309 if (function->has_instance_prototype()) { |
10310 prototype = handle(function->instance_prototype(), isolate); | 10310 prototype = handle(function->instance_prototype(), isolate); |
10311 } else { | 10311 } else { |
10312 prototype = isolate->factory()->NewFunctionPrototype(function); | 10312 prototype = isolate->factory()->NewFunctionPrototype(function); |
10313 } | 10313 } |
10314 map->set_inobject_properties(in_object_properties); | 10314 map->set_inobject_properties(in_object_properties); |
10315 map->set_unused_property_fields(in_object_properties); | 10315 map->set_unused_property_fields(in_object_properties); |
10316 map->set_prototype(*prototype); | 10316 map->set_prototype(*prototype); |
10317 ASSERT(map->has_fast_object_elements()); | 10317 ASSERT(map->has_fast_object_elements()); |
10318 | 10318 |
10319 if (!function->shared()->is_generator()) { | |
10320 function->shared()->StartInobjectSlackTracking(*map); | |
10321 } | |
10322 | |
10323 // Finally link initial map and constructor function. | 10319 // Finally link initial map and constructor function. |
10324 function->set_initial_map(*map); | 10320 function->set_initial_map(*map); |
10325 map->set_constructor(*function); | 10321 map->set_constructor(*function); |
| 10322 |
| 10323 if (!function->shared()->is_generator()) { |
| 10324 function->StartInobjectSlackTracking(); |
| 10325 } |
10326 } | 10326 } |
10327 | 10327 |
10328 | 10328 |
10329 void JSFunction::SetInstanceClassName(String* name) { | 10329 void JSFunction::SetInstanceClassName(String* name) { |
10330 shared()->set_instance_class_name(name); | 10330 shared()->set_instance_class_name(name); |
10331 } | 10331 } |
10332 | 10332 |
10333 | 10333 |
10334 void JSFunction::PrintName(FILE* out) { | 10334 void JSFunction::PrintName(FILE* out) { |
10335 SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); | 10335 SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10702 ASSERT(!id.IsNone()); | 10702 ASSERT(!id.IsNone()); |
10703 Code* unoptimized = code(); | 10703 Code* unoptimized = code(); |
10704 DeoptimizationOutputData* data = | 10704 DeoptimizationOutputData* data = |
10705 DeoptimizationOutputData::cast(unoptimized->deoptimization_data()); | 10705 DeoptimizationOutputData::cast(unoptimized->deoptimization_data()); |
10706 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this); | 10706 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this); |
10707 USE(ignore); | 10707 USE(ignore); |
10708 return true; // Return true if there was no ASSERT. | 10708 return true; // Return true if there was no ASSERT. |
10709 } | 10709 } |
10710 | 10710 |
10711 | 10711 |
10712 void SharedFunctionInfo::StartInobjectSlackTracking(Map* map) { | 10712 void JSFunction::StartInobjectSlackTracking() { |
10713 ASSERT(!IsInobjectSlackTrackingInProgress()); | 10713 ASSERT(has_initial_map() && !IsInobjectSlackTrackingInProgress()); |
10714 | 10714 |
10715 if (!FLAG_clever_optimizations) return; | 10715 if (!FLAG_clever_optimizations) return; |
| 10716 Map* map = initial_map(); |
10716 | 10717 |
10717 // Only initiate the tracking the first time. | 10718 // Only initiate the tracking the first time. |
10718 if (live_objects_may_exist()) return; | 10719 if (map->done_inobject_slack_tracking()) return; |
10719 set_live_objects_may_exist(true); | 10720 map->set_done_inobject_slack_tracking(true); |
10720 | 10721 |
10721 // No tracking during the snapshot construction phase. | 10722 // No tracking during the snapshot construction phase. |
10722 Isolate* isolate = GetIsolate(); | 10723 Isolate* isolate = GetIsolate(); |
10723 if (Serializer::enabled(isolate)) return; | 10724 if (Serializer::enabled(isolate)) return; |
10724 | 10725 |
10725 if (map->unused_property_fields() == 0) return; | 10726 if (map->unused_property_fields() == 0) return; |
10726 | 10727 |
10727 // Nonzero counter is a leftover from the previous attempt interrupted | 10728 map->set_construction_count(kGenerousAllocationCount); |
10728 // by GC, keep it. | |
10729 if (construction_count() == 0) { | |
10730 set_construction_count(kGenerousAllocationCount); | |
10731 } | |
10732 set_initial_map(map); | |
10733 Builtins* builtins = isolate->builtins(); | |
10734 ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubGeneric), | |
10735 construct_stub()); | |
10736 set_construct_stub(builtins->builtin(Builtins::kJSConstructStubCountdown)); | |
10737 } | 10729 } |
10738 | 10730 |
10739 | 10731 |
10740 // Called from GC, hence reinterpret_cast and unchecked accessors. | |
10741 void SharedFunctionInfo::DetachInitialMap() { | |
10742 Map* map = reinterpret_cast<Map*>(initial_map()); | |
10743 | |
10744 // Make the map remember to restore the link if it survives the GC. | |
10745 map->set_bit_field2( | |
10746 map->bit_field2() | (1 << Map::kAttachedToSharedFunctionInfo)); | |
10747 | |
10748 // Undo state changes made by StartInobjectTracking (except the | |
10749 // construction_count). This way if the initial map does not survive the GC | |
10750 // then StartInobjectTracking will be called again the next time the | |
10751 // constructor is called. The countdown will continue and (possibly after | |
10752 // several more GCs) CompleteInobjectSlackTracking will eventually be called. | |
10753 Heap* heap = map->GetHeap(); | |
10754 set_initial_map(heap->undefined_value()); | |
10755 Builtins* builtins = heap->isolate()->builtins(); | |
10756 ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubCountdown), | |
10757 *RawField(this, kConstructStubOffset)); | |
10758 set_construct_stub(builtins->builtin(Builtins::kJSConstructStubGeneric)); | |
10759 // It is safe to clear the flag: it will be set again if the map is live. | |
10760 set_live_objects_may_exist(false); | |
10761 } | |
10762 | |
10763 | |
10764 // Called from GC, hence reinterpret_cast and unchecked accessors. | |
10765 void SharedFunctionInfo::AttachInitialMap(Map* map) { | |
10766 map->set_bit_field2( | |
10767 map->bit_field2() & ~(1 << Map::kAttachedToSharedFunctionInfo)); | |
10768 | |
10769 // Resume inobject slack tracking. | |
10770 set_initial_map(map); | |
10771 Builtins* builtins = map->GetHeap()->isolate()->builtins(); | |
10772 ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubGeneric), | |
10773 *RawField(this, kConstructStubOffset)); | |
10774 set_construct_stub(builtins->builtin(Builtins::kJSConstructStubCountdown)); | |
10775 // The map survived the gc, so there may be objects referencing it. | |
10776 set_live_objects_may_exist(true); | |
10777 } | |
10778 | |
10779 | |
10780 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { | 10732 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { |
10781 code()->ClearInlineCaches(); | 10733 code()->ClearInlineCaches(); |
10782 // If we clear ICs, we need to clear the type feedback vector too, since | 10734 // If we clear ICs, we need to clear the type feedback vector too, since |
10783 // CallICs are synced with a feedback vector slot. | 10735 // CallICs are synced with a feedback vector slot. |
10784 ClearTypeFeedbackInfo(); | 10736 ClearTypeFeedbackInfo(); |
10785 set_ic_age(new_ic_age); | 10737 set_ic_age(new_ic_age); |
10786 if (code()->kind() == Code::FUNCTION) { | 10738 if (code()->kind() == Code::FUNCTION) { |
10787 code()->set_profiler_ticks(0); | 10739 code()->set_profiler_ticks(0); |
10788 if (optimization_disabled() && | 10740 if (optimization_disabled() && |
10789 opt_count() >= FLAG_max_opt_count) { | 10741 opt_count() >= FLAG_max_opt_count) { |
(...skipping 19 matching lines...) Expand all Loading... |
10809 int slack = *reinterpret_cast<int*>(data); | 10761 int slack = *reinterpret_cast<int*>(data); |
10810 map->set_inobject_properties(map->inobject_properties() - slack); | 10762 map->set_inobject_properties(map->inobject_properties() - slack); |
10811 map->set_unused_property_fields(map->unused_property_fields() - slack); | 10763 map->set_unused_property_fields(map->unused_property_fields() - slack); |
10812 map->set_instance_size(map->instance_size() - slack * kPointerSize); | 10764 map->set_instance_size(map->instance_size() - slack * kPointerSize); |
10813 | 10765 |
10814 // Visitor id might depend on the instance size, recalculate it. | 10766 // Visitor id might depend on the instance size, recalculate it. |
10815 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); | 10767 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); |
10816 } | 10768 } |
10817 | 10769 |
10818 | 10770 |
10819 void SharedFunctionInfo::CompleteInobjectSlackTracking() { | 10771 void JSFunction::CompleteInobjectSlackTracking() { |
10820 ASSERT(live_objects_may_exist() && IsInobjectSlackTrackingInProgress()); | 10772 ASSERT(has_initial_map()); |
10821 Map* map = Map::cast(initial_map()); | 10773 Map* map = initial_map(); |
10822 | 10774 |
10823 Heap* heap = map->GetHeap(); | 10775 ASSERT(map->done_inobject_slack_tracking()); |
10824 set_initial_map(heap->undefined_value()); | 10776 map->set_construction_count(kNoSlackTracking); |
10825 Builtins* builtins = heap->isolate()->builtins(); | |
10826 ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubCountdown), | |
10827 construct_stub()); | |
10828 set_construct_stub(builtins->builtin(Builtins::kJSConstructStubGeneric)); | |
10829 | 10777 |
10830 int slack = map->unused_property_fields(); | 10778 int slack = map->unused_property_fields(); |
10831 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); | 10779 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); |
10832 if (slack != 0) { | 10780 if (slack != 0) { |
10833 // Resize the initial map and all maps in its transition tree. | 10781 // Resize the initial map and all maps in its transition tree. |
10834 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); | 10782 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); |
10835 | |
10836 // Give the correct expected_nof_properties to initial maps created later. | |
10837 ASSERT(expected_nof_properties() >= slack); | |
10838 set_expected_nof_properties(expected_nof_properties() - slack); | |
10839 } | 10783 } |
10840 } | 10784 } |
10841 | 10785 |
10842 | 10786 |
10843 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context, | 10787 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context, |
10844 BailoutId osr_ast_id) { | 10788 BailoutId osr_ast_id) { |
10845 DisallowHeapAllocation no_gc; | 10789 DisallowHeapAllocation no_gc; |
10846 ASSERT(native_context->IsNativeContext()); | 10790 ASSERT(native_context->IsNativeContext()); |
10847 if (!FLAG_cache_optimized_code) return -1; | 10791 if (!FLAG_cache_optimized_code) return -1; |
10848 Object* value = optimized_code_map(); | 10792 Object* value = optimized_code_map(); |
(...skipping 6425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17274 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17218 #define ERROR_MESSAGES_TEXTS(C, T) T, |
17275 static const char* error_messages_[] = { | 17219 static const char* error_messages_[] = { |
17276 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17220 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
17277 }; | 17221 }; |
17278 #undef ERROR_MESSAGES_TEXTS | 17222 #undef ERROR_MESSAGES_TEXTS |
17279 return error_messages_[reason]; | 17223 return error_messages_[reason]; |
17280 } | 17224 } |
17281 | 17225 |
17282 | 17226 |
17283 } } // namespace v8::internal | 17227 } } // namespace v8::internal |
OLD | NEW |