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

Side by Side Diff: src/objects.cc

Issue 290993009: Reland r21346 "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 10207 matching lines...) Expand 10 before | Expand all | Expand 10 after
10218 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); 10218 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
10219 } 10219 }
10220 10220
10221 // Now some logic for the maps of the objects that are created by using this 10221 // Now some logic for the maps of the objects that are created by using this
10222 // function as a constructor. 10222 // function as a constructor.
10223 if (function->has_initial_map()) { 10223 if (function->has_initial_map()) {
10224 // If the function has allocated the initial map replace it with a 10224 // If the function has allocated the initial map replace it with a
10225 // copy containing the new prototype. Also complete any in-object 10225 // copy containing the new prototype. Also complete any in-object
10226 // slack tracking that is in progress at this point because it is 10226 // slack tracking that is in progress at this point because it is
10227 // still tracking the old copy. 10227 // still tracking the old copy.
10228 if (function->shared()->IsInobjectSlackTrackingInProgress()) { 10228 if (function->IsInobjectSlackTrackingInProgress()) {
10229 function->shared()->CompleteInobjectSlackTracking(); 10229 function->CompleteInobjectSlackTracking();
10230 } 10230 }
10231 Handle<Map> new_map = Map::Copy(handle(function->initial_map())); 10231 Handle<Map> new_map = Map::Copy(handle(function->initial_map()));
10232 new_map->set_prototype(*value); 10232 new_map->set_prototype(*value);
10233 10233
10234 // If the function is used as the global Array function, cache the 10234 // If the function is used as the global Array function, cache the
10235 // initial map (and transitioned versions) in the native context. 10235 // initial map (and transitioned versions) in the native context.
10236 Context* native_context = function->context()->native_context(); 10236 Context* native_context = function->context()->native_context();
10237 Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX); 10237 Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX);
10238 if (array_function->IsJSFunction() && 10238 if (array_function->IsJSFunction() &&
10239 *function == JSFunction::cast(array_function)) { 10239 *function == JSFunction::cast(array_function)) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
10328 if (function->has_instance_prototype()) { 10328 if (function->has_instance_prototype()) {
10329 prototype = handle(function->instance_prototype(), isolate); 10329 prototype = handle(function->instance_prototype(), isolate);
10330 } else { 10330 } else {
10331 prototype = isolate->factory()->NewFunctionPrototype(function); 10331 prototype = isolate->factory()->NewFunctionPrototype(function);
10332 } 10332 }
10333 map->set_inobject_properties(in_object_properties); 10333 map->set_inobject_properties(in_object_properties);
10334 map->set_unused_property_fields(in_object_properties); 10334 map->set_unused_property_fields(in_object_properties);
10335 map->set_prototype(*prototype); 10335 map->set_prototype(*prototype);
10336 ASSERT(map->has_fast_object_elements()); 10336 ASSERT(map->has_fast_object_elements());
10337 10337
10338 if (!function->shared()->is_generator()) {
10339 function->shared()->StartInobjectSlackTracking(*map);
10340 }
10341
10342 // Finally link initial map and constructor function. 10338 // Finally link initial map and constructor function.
10343 function->set_initial_map(*map); 10339 function->set_initial_map(*map);
10344 map->set_constructor(*function); 10340 map->set_constructor(*function);
10341
10342 if (!function->shared()->is_generator()) {
10343 function->StartInobjectSlackTracking();
10344 }
10345 } 10345 }
10346 10346
10347 10347
10348 void JSFunction::SetInstanceClassName(String* name) { 10348 void JSFunction::SetInstanceClassName(String* name) {
10349 shared()->set_instance_class_name(name); 10349 shared()->set_instance_class_name(name);
10350 } 10350 }
10351 10351
10352 10352
10353 void JSFunction::PrintName(FILE* out) { 10353 void JSFunction::PrintName(FILE* out) {
10354 SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); 10354 SmartArrayPointer<char> name = shared()->DebugName()->ToCString();
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
10719 ASSERT(!id.IsNone()); 10719 ASSERT(!id.IsNone());
10720 Code* unoptimized = code(); 10720 Code* unoptimized = code();
10721 DeoptimizationOutputData* data = 10721 DeoptimizationOutputData* data =
10722 DeoptimizationOutputData::cast(unoptimized->deoptimization_data()); 10722 DeoptimizationOutputData::cast(unoptimized->deoptimization_data());
10723 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this); 10723 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this);
10724 USE(ignore); 10724 USE(ignore);
10725 return true; // Return true if there was no ASSERT. 10725 return true; // Return true if there was no ASSERT.
10726 } 10726 }
10727 10727
10728 10728
10729 void SharedFunctionInfo::StartInobjectSlackTracking(Map* map) { 10729 void JSFunction::StartInobjectSlackTracking() {
10730 ASSERT(!IsInobjectSlackTrackingInProgress()); 10730 ASSERT(has_initial_map() && !IsInobjectSlackTrackingInProgress());
10731 10731
10732 if (!FLAG_clever_optimizations) return; 10732 if (!FLAG_clever_optimizations) return;
10733 Map* map = initial_map();
10733 10734
10734 // Only initiate the tracking the first time. 10735 // Only initiate the tracking the first time.
10735 if (live_objects_may_exist()) return; 10736 if (map->done_inobject_slack_tracking()) return;
10736 set_live_objects_may_exist(true); 10737 map->set_done_inobject_slack_tracking(true);
10737 10738
10738 // No tracking during the snapshot construction phase. 10739 // No tracking during the snapshot construction phase.
10739 Isolate* isolate = GetIsolate(); 10740 Isolate* isolate = GetIsolate();
10740 if (isolate->serializer_enabled()) return; 10741 if (isolate->serializer_enabled()) return;
10741 10742
10742 if (map->unused_property_fields() == 0) return; 10743 if (map->unused_property_fields() == 0) return;
10743 10744
10744 // Nonzero counter is a leftover from the previous attempt interrupted 10745 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 } 10746 }
10755 10747
10756 10748
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) { 10749 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) {
10798 code()->ClearInlineCaches(); 10750 code()->ClearInlineCaches();
10799 // If we clear ICs, we need to clear the type feedback vector too, since 10751 // If we clear ICs, we need to clear the type feedback vector too, since
10800 // CallICs are synced with a feedback vector slot. 10752 // CallICs are synced with a feedback vector slot.
10801 ClearTypeFeedbackInfo(); 10753 ClearTypeFeedbackInfo();
10802 set_ic_age(new_ic_age); 10754 set_ic_age(new_ic_age);
10803 if (code()->kind() == Code::FUNCTION) { 10755 if (code()->kind() == Code::FUNCTION) {
10804 code()->set_profiler_ticks(0); 10756 code()->set_profiler_ticks(0);
10805 if (optimization_disabled() && 10757 if (optimization_disabled() &&
10806 opt_count() >= FLAG_max_opt_count) { 10758 opt_count() >= FLAG_max_opt_count) {
(...skipping 19 matching lines...) Expand all
10826 int slack = *reinterpret_cast<int*>(data); 10778 int slack = *reinterpret_cast<int*>(data);
10827 map->set_inobject_properties(map->inobject_properties() - slack); 10779 map->set_inobject_properties(map->inobject_properties() - slack);
10828 map->set_unused_property_fields(map->unused_property_fields() - slack); 10780 map->set_unused_property_fields(map->unused_property_fields() - slack);
10829 map->set_instance_size(map->instance_size() - slack * kPointerSize); 10781 map->set_instance_size(map->instance_size() - slack * kPointerSize);
10830 10782
10831 // Visitor id might depend on the instance size, recalculate it. 10783 // Visitor id might depend on the instance size, recalculate it.
10832 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); 10784 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map));
10833 } 10785 }
10834 10786
10835 10787
10836 void SharedFunctionInfo::CompleteInobjectSlackTracking() { 10788 void JSFunction::CompleteInobjectSlackTracking() {
10837 ASSERT(live_objects_may_exist() && IsInobjectSlackTrackingInProgress()); 10789 ASSERT(has_initial_map());
10838 Map* map = Map::cast(initial_map()); 10790 Map* map = initial_map();
10839 10791
10840 Heap* heap = map->GetHeap(); 10792 ASSERT(map->done_inobject_slack_tracking());
10841 set_initial_map(heap->undefined_value()); 10793 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 10794
10847 int slack = map->unused_property_fields(); 10795 int slack = map->unused_property_fields();
10848 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); 10796 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack);
10849 if (slack != 0) { 10797 if (slack != 0) {
10850 // Resize the initial map and all maps in its transition tree. 10798 // Resize the initial map and all maps in its transition tree.
10851 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); 10799 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 } 10800 }
10857 } 10801 }
10858 10802
10859 10803
10860 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context, 10804 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
10861 BailoutId osr_ast_id) { 10805 BailoutId osr_ast_id) {
10862 DisallowHeapAllocation no_gc; 10806 DisallowHeapAllocation no_gc;
10863 ASSERT(native_context->IsNativeContext()); 10807 ASSERT(native_context->IsNativeContext());
10864 if (!FLAG_cache_optimized_code) return -1; 10808 if (!FLAG_cache_optimized_code) return -1;
10865 Object* value = optimized_code_map(); 10809 Object* value = optimized_code_map();
(...skipping 6444 matching lines...) Expand 10 before | Expand all | Expand 10 after
17310 #define ERROR_MESSAGES_TEXTS(C, T) T, 17254 #define ERROR_MESSAGES_TEXTS(C, T) T,
17311 static const char* error_messages_[] = { 17255 static const char* error_messages_[] = {
17312 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 17256 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
17313 }; 17257 };
17314 #undef ERROR_MESSAGES_TEXTS 17258 #undef ERROR_MESSAGES_TEXTS
17315 return error_messages_[reason]; 17259 return error_messages_[reason];
17316 } 17260 }
17317 17261
17318 17262
17319 } } // namespace v8::internal 17263 } } // 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