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 7239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7250 result->set_bit_field2(map->bit_field2()); | 7250 result->set_bit_field2(map->bit_field2()); |
7251 int new_bit_field3 = map->bit_field3(); | 7251 int new_bit_field3 = map->bit_field3(); |
7252 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); | 7252 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); |
7253 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); | 7253 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); |
7254 new_bit_field3 = EnumLengthBits::update(new_bit_field3, | 7254 new_bit_field3 = EnumLengthBits::update(new_bit_field3, |
7255 kInvalidEnumCacheSentinel); | 7255 kInvalidEnumCacheSentinel); |
7256 new_bit_field3 = Deprecated::update(new_bit_field3, false); | 7256 new_bit_field3 = Deprecated::update(new_bit_field3, false); |
7257 if (!map->is_dictionary_map()) { | 7257 if (!map->is_dictionary_map()) { |
7258 new_bit_field3 = IsUnstable::update(new_bit_field3, false); | 7258 new_bit_field3 = IsUnstable::update(new_bit_field3, false); |
7259 } | 7259 } |
| 7260 new_bit_field3 = ConstructionCount::update(new_bit_field3, |
| 7261 JSFunction::kNoSlackTracking); |
7260 result->set_bit_field3(new_bit_field3); | 7262 result->set_bit_field3(new_bit_field3); |
7261 return result; | 7263 return result; |
7262 } | 7264 } |
7263 | 7265 |
7264 | 7266 |
7265 Handle<Map> Map::Normalize(Handle<Map> fast_map, | 7267 Handle<Map> Map::Normalize(Handle<Map> fast_map, |
7266 PropertyNormalizationMode mode) { | 7268 PropertyNormalizationMode mode) { |
7267 ASSERT(!fast_map->is_dictionary_map()); | 7269 ASSERT(!fast_map->is_dictionary_map()); |
7268 | 7270 |
7269 Isolate* isolate = fast_map->GetIsolate(); | 7271 Isolate* isolate = fast_map->GetIsolate(); |
(...skipping 2948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10218 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); | 10220 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); |
10219 } | 10221 } |
10220 | 10222 |
10221 // Now some logic for the maps of the objects that are created by using this | 10223 // Now some logic for the maps of the objects that are created by using this |
10222 // function as a constructor. | 10224 // function as a constructor. |
10223 if (function->has_initial_map()) { | 10225 if (function->has_initial_map()) { |
10224 // If the function has allocated the initial map replace it with a | 10226 // If the function has allocated the initial map replace it with a |
10225 // copy containing the new prototype. Also complete any in-object | 10227 // copy containing the new prototype. Also complete any in-object |
10226 // slack tracking that is in progress at this point because it is | 10228 // slack tracking that is in progress at this point because it is |
10227 // still tracking the old copy. | 10229 // still tracking the old copy. |
10228 if (function->shared()->IsInobjectSlackTrackingInProgress()) { | 10230 if (function->IsInobjectSlackTrackingInProgress()) { |
10229 function->shared()->CompleteInobjectSlackTracking(); | 10231 function->CompleteInobjectSlackTracking(); |
10230 } | 10232 } |
10231 Handle<Map> new_map = Map::Copy(handle(function->initial_map())); | 10233 Handle<Map> new_map = Map::Copy(handle(function->initial_map())); |
10232 new_map->set_prototype(*value); | 10234 new_map->set_prototype(*value); |
10233 | 10235 |
10234 // If the function is used as the global Array function, cache the | 10236 // If the function is used as the global Array function, cache the |
10235 // initial map (and transitioned versions) in the native context. | 10237 // initial map (and transitioned versions) in the native context. |
10236 Context* native_context = function->context()->native_context(); | 10238 Context* native_context = function->context()->native_context(); |
10237 Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX); | 10239 Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX); |
10238 if (array_function->IsJSFunction() && | 10240 if (array_function->IsJSFunction() && |
10239 *function == JSFunction::cast(array_function)) { | 10241 *function == JSFunction::cast(array_function)) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10328 if (function->has_instance_prototype()) { | 10330 if (function->has_instance_prototype()) { |
10329 prototype = handle(function->instance_prototype(), isolate); | 10331 prototype = handle(function->instance_prototype(), isolate); |
10330 } else { | 10332 } else { |
10331 prototype = isolate->factory()->NewFunctionPrototype(function); | 10333 prototype = isolate->factory()->NewFunctionPrototype(function); |
10332 } | 10334 } |
10333 map->set_inobject_properties(in_object_properties); | 10335 map->set_inobject_properties(in_object_properties); |
10334 map->set_unused_property_fields(in_object_properties); | 10336 map->set_unused_property_fields(in_object_properties); |
10335 map->set_prototype(*prototype); | 10337 map->set_prototype(*prototype); |
10336 ASSERT(map->has_fast_object_elements()); | 10338 ASSERT(map->has_fast_object_elements()); |
10337 | 10339 |
10338 if (!function->shared()->is_generator()) { | |
10339 function->shared()->StartInobjectSlackTracking(*map); | |
10340 } | |
10341 | |
10342 // Finally link initial map and constructor function. | 10340 // Finally link initial map and constructor function. |
10343 function->set_initial_map(*map); | 10341 function->set_initial_map(*map); |
10344 map->set_constructor(*function); | 10342 map->set_constructor(*function); |
| 10343 |
| 10344 if (!function->shared()->is_generator()) { |
| 10345 function->StartInobjectSlackTracking(); |
| 10346 } |
10345 } | 10347 } |
10346 | 10348 |
10347 | 10349 |
10348 void JSFunction::SetInstanceClassName(String* name) { | 10350 void JSFunction::SetInstanceClassName(String* name) { |
10349 shared()->set_instance_class_name(name); | 10351 shared()->set_instance_class_name(name); |
10350 } | 10352 } |
10351 | 10353 |
10352 | 10354 |
10353 void JSFunction::PrintName(FILE* out) { | 10355 void JSFunction::PrintName(FILE* out) { |
10354 SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); | 10356 SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10719 ASSERT(!id.IsNone()); | 10721 ASSERT(!id.IsNone()); |
10720 Code* unoptimized = code(); | 10722 Code* unoptimized = code(); |
10721 DeoptimizationOutputData* data = | 10723 DeoptimizationOutputData* data = |
10722 DeoptimizationOutputData::cast(unoptimized->deoptimization_data()); | 10724 DeoptimizationOutputData::cast(unoptimized->deoptimization_data()); |
10723 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this); | 10725 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this); |
10724 USE(ignore); | 10726 USE(ignore); |
10725 return true; // Return true if there was no ASSERT. | 10727 return true; // Return true if there was no ASSERT. |
10726 } | 10728 } |
10727 | 10729 |
10728 | 10730 |
10729 void SharedFunctionInfo::StartInobjectSlackTracking(Map* map) { | 10731 void JSFunction::StartInobjectSlackTracking() { |
10730 ASSERT(!IsInobjectSlackTrackingInProgress()); | 10732 ASSERT(has_initial_map() && !IsInobjectSlackTrackingInProgress()); |
10731 | 10733 |
10732 if (!FLAG_clever_optimizations) return; | 10734 if (!FLAG_clever_optimizations) return; |
| 10735 Map* map = initial_map(); |
10733 | 10736 |
10734 // Only initiate the tracking the first time. | 10737 // Only initiate the tracking the first time. |
10735 if (live_objects_may_exist()) return; | 10738 if (map->done_inobject_slack_tracking()) return; |
10736 set_live_objects_may_exist(true); | 10739 map->set_done_inobject_slack_tracking(true); |
10737 | 10740 |
10738 // No tracking during the snapshot construction phase. | 10741 // No tracking during the snapshot construction phase. |
10739 Isolate* isolate = GetIsolate(); | 10742 Isolate* isolate = GetIsolate(); |
10740 if (isolate->serializer_enabled()) return; | 10743 if (isolate->serializer_enabled()) return; |
10741 | 10744 |
10742 if (map->unused_property_fields() == 0) return; | 10745 if (map->unused_property_fields() == 0) return; |
10743 | 10746 |
10744 // Nonzero counter is a leftover from the previous attempt interrupted | 10747 map->set_construction_count(kGenerousAllocationCount); |
10745 // by GC, keep it. | |
10746 if (construction_count() == 0) { | |
10747 set_construction_count(kGenerousAllocationCount); | |
10748 } | |
10749 set_initial_map(map); | |
10750 Builtins* builtins = isolate->builtins(); | |
10751 ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubGeneric), | |
10752 construct_stub()); | |
10753 set_construct_stub(builtins->builtin(Builtins::kJSConstructStubCountdown)); | |
10754 } | 10748 } |
10755 | 10749 |
10756 | 10750 |
10757 // Called from GC, hence reinterpret_cast and unchecked accessors. | |
10758 void SharedFunctionInfo::DetachInitialMap() { | |
10759 Map* map = reinterpret_cast<Map*>(initial_map()); | |
10760 | |
10761 // Make the map remember to restore the link if it survives the GC. | |
10762 map->set_bit_field2( | |
10763 map->bit_field2() | (1 << Map::kAttachedToSharedFunctionInfo)); | |
10764 | |
10765 // Undo state changes made by StartInobjectTracking (except the | |
10766 // construction_count). This way if the initial map does not survive the GC | |
10767 // then StartInobjectTracking will be called again the next time the | |
10768 // constructor is called. The countdown will continue and (possibly after | |
10769 // several more GCs) CompleteInobjectSlackTracking will eventually be called. | |
10770 Heap* heap = map->GetHeap(); | |
10771 set_initial_map(heap->undefined_value()); | |
10772 Builtins* builtins = heap->isolate()->builtins(); | |
10773 ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubCountdown), | |
10774 *RawField(this, kConstructStubOffset)); | |
10775 set_construct_stub(builtins->builtin(Builtins::kJSConstructStubGeneric)); | |
10776 // It is safe to clear the flag: it will be set again if the map is live. | |
10777 set_live_objects_may_exist(false); | |
10778 } | |
10779 | |
10780 | |
10781 // Called from GC, hence reinterpret_cast and unchecked accessors. | |
10782 void SharedFunctionInfo::AttachInitialMap(Map* map) { | |
10783 map->set_bit_field2( | |
10784 map->bit_field2() & ~(1 << Map::kAttachedToSharedFunctionInfo)); | |
10785 | |
10786 // Resume inobject slack tracking. | |
10787 set_initial_map(map); | |
10788 Builtins* builtins = map->GetHeap()->isolate()->builtins(); | |
10789 ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubGeneric), | |
10790 *RawField(this, kConstructStubOffset)); | |
10791 set_construct_stub(builtins->builtin(Builtins::kJSConstructStubCountdown)); | |
10792 // The map survived the gc, so there may be objects referencing it. | |
10793 set_live_objects_may_exist(true); | |
10794 } | |
10795 | |
10796 | |
10797 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { | 10751 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { |
10798 code()->ClearInlineCaches(); | 10752 code()->ClearInlineCaches(); |
10799 // If we clear ICs, we need to clear the type feedback vector too, since | 10753 // If we clear ICs, we need to clear the type feedback vector too, since |
10800 // CallICs are synced with a feedback vector slot. | 10754 // CallICs are synced with a feedback vector slot. |
10801 ClearTypeFeedbackInfo(); | 10755 ClearTypeFeedbackInfo(); |
10802 set_ic_age(new_ic_age); | 10756 set_ic_age(new_ic_age); |
10803 if (code()->kind() == Code::FUNCTION) { | 10757 if (code()->kind() == Code::FUNCTION) { |
10804 code()->set_profiler_ticks(0); | 10758 code()->set_profiler_ticks(0); |
10805 if (optimization_disabled() && | 10759 if (optimization_disabled() && |
10806 opt_count() >= FLAG_max_opt_count) { | 10760 opt_count() >= FLAG_max_opt_count) { |
(...skipping 19 matching lines...) Expand all Loading... |
10826 int slack = *reinterpret_cast<int*>(data); | 10780 int slack = *reinterpret_cast<int*>(data); |
10827 map->set_inobject_properties(map->inobject_properties() - slack); | 10781 map->set_inobject_properties(map->inobject_properties() - slack); |
10828 map->set_unused_property_fields(map->unused_property_fields() - slack); | 10782 map->set_unused_property_fields(map->unused_property_fields() - slack); |
10829 map->set_instance_size(map->instance_size() - slack * kPointerSize); | 10783 map->set_instance_size(map->instance_size() - slack * kPointerSize); |
10830 | 10784 |
10831 // Visitor id might depend on the instance size, recalculate it. | 10785 // Visitor id might depend on the instance size, recalculate it. |
10832 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); | 10786 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); |
10833 } | 10787 } |
10834 | 10788 |
10835 | 10789 |
10836 void SharedFunctionInfo::CompleteInobjectSlackTracking() { | 10790 void JSFunction::CompleteInobjectSlackTracking() { |
10837 ASSERT(live_objects_may_exist() && IsInobjectSlackTrackingInProgress()); | 10791 ASSERT(has_initial_map()); |
10838 Map* map = Map::cast(initial_map()); | 10792 Map* map = initial_map(); |
10839 | 10793 |
10840 Heap* heap = map->GetHeap(); | 10794 ASSERT(map->done_inobject_slack_tracking()); |
10841 set_initial_map(heap->undefined_value()); | 10795 map->set_construction_count(kNoSlackTracking); |
10842 Builtins* builtins = heap->isolate()->builtins(); | |
10843 ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubCountdown), | |
10844 construct_stub()); | |
10845 set_construct_stub(builtins->builtin(Builtins::kJSConstructStubGeneric)); | |
10846 | 10796 |
10847 int slack = map->unused_property_fields(); | 10797 int slack = map->unused_property_fields(); |
10848 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); | 10798 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); |
10849 if (slack != 0) { | 10799 if (slack != 0) { |
10850 // Resize the initial map and all maps in its transition tree. | 10800 // Resize the initial map and all maps in its transition tree. |
10851 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); | 10801 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); |
10852 | |
10853 // Give the correct expected_nof_properties to initial maps created later. | |
10854 ASSERT(expected_nof_properties() >= slack); | |
10855 set_expected_nof_properties(expected_nof_properties() - slack); | |
10856 } | 10802 } |
10857 } | 10803 } |
10858 | 10804 |
10859 | 10805 |
10860 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context, | 10806 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context, |
10861 BailoutId osr_ast_id) { | 10807 BailoutId osr_ast_id) { |
10862 DisallowHeapAllocation no_gc; | 10808 DisallowHeapAllocation no_gc; |
10863 ASSERT(native_context->IsNativeContext()); | 10809 ASSERT(native_context->IsNativeContext()); |
10864 if (!FLAG_cache_optimized_code) return -1; | 10810 if (!FLAG_cache_optimized_code) return -1; |
10865 Object* value = optimized_code_map(); | 10811 Object* value = optimized_code_map(); |
(...skipping 6443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17309 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17255 #define ERROR_MESSAGES_TEXTS(C, T) T, |
17310 static const char* error_messages_[] = { | 17256 static const char* error_messages_[] = { |
17311 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17257 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
17312 }; | 17258 }; |
17313 #undef ERROR_MESSAGES_TEXTS | 17259 #undef ERROR_MESSAGES_TEXTS |
17314 return error_messages_[reason]; | 17260 return error_messages_[reason]; |
17315 } | 17261 } |
17316 | 17262 |
17317 | 17263 |
17318 } } // namespace v8::internal | 17264 } } // namespace v8::internal |
OLD | NEW |