| 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 |