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

Side by Side Diff: src/objects.cc

Issue 283383006: Inobject slack tracking is done on a per-closure basis instead of per-shared info basis. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressing review comments 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 10188 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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