Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Side by Side Diff: src/objects.cc

Issue 292183008: Reland r21442 "Inobject slack tracking is done on a per-closure basis instead of per-shared info ba… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: The fix Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698