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

Side by Side Diff: src/objects.cc

Issue 1488023002: Fix inobject slack tracking for both subclassing and non-subclassing cases. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Moved and updated comments about slack tracking Created 5 years 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
« 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 "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 #include "src/zone.h" 50 #include "src/zone.h"
51 51
52 #ifdef ENABLE_DISASSEMBLER 52 #ifdef ENABLE_DISASSEMBLER
53 #include "src/disasm.h" 53 #include "src/disasm.h"
54 #include "src/disassembler.h" 54 #include "src/disassembler.h"
55 #endif 55 #endif
56 56
57 namespace v8 { 57 namespace v8 {
58 namespace internal { 58 namespace internal {
59 59
60 std::ostream& operator<<(std::ostream& os, InstanceType instance_type) {
61 switch (instance_type) {
62 #define WRITE_TYPE(TYPE) \
63 case TYPE: \
64 return os << #TYPE;
65 INSTANCE_TYPE_LIST(WRITE_TYPE)
66 #undef WRITE_TYPE
67 }
68 UNREACHABLE();
69 return os << "UNKNOWN"; // Keep the compiler happy.
70 }
71
72
60 Handle<HeapType> Object::OptimalType(Isolate* isolate, 73 Handle<HeapType> Object::OptimalType(Isolate* isolate,
61 Representation representation) { 74 Representation representation) {
62 if (representation.IsNone()) return HeapType::None(isolate); 75 if (representation.IsNone()) return HeapType::None(isolate);
63 if (FLAG_track_field_types) { 76 if (FLAG_track_field_types) {
64 if (representation.IsHeapObject() && IsHeapObject()) { 77 if (representation.IsHeapObject() && IsHeapObject()) {
65 // We can track only JavaScript objects with stable maps. 78 // We can track only JavaScript objects with stable maps.
66 Handle<Map> map(HeapObject::cast(this)->map(), isolate); 79 Handle<Map> map(HeapObject::cast(this)->map(), isolate);
67 if (map->is_stable() && 80 if (map->is_stable() &&
68 map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE && 81 map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
69 map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) { 82 map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) {
(...skipping 11935 matching lines...) Expand 10 before | Expand all | Expand 10 after
12005 int slack = *reinterpret_cast<int*>(data); 12018 int slack = *reinterpret_cast<int*>(data);
12006 map->SetInObjectProperties(map->GetInObjectProperties() - slack); 12019 map->SetInObjectProperties(map->GetInObjectProperties() - slack);
12007 map->set_unused_property_fields(map->unused_property_fields() - slack); 12020 map->set_unused_property_fields(map->unused_property_fields() - slack);
12008 map->set_instance_size(map->instance_size() - slack * kPointerSize); 12021 map->set_instance_size(map->instance_size() - slack * kPointerSize);
12009 12022
12010 // Visitor id might depend on the instance size, recalculate it. 12023 // Visitor id might depend on the instance size, recalculate it.
12011 map->set_visitor_id(Heap::GetStaticVisitorIdForMap(map)); 12024 map->set_visitor_id(Heap::GetStaticVisitorIdForMap(map));
12012 } 12025 }
12013 12026
12014 12027
12015 void JSFunction::CompleteInobjectSlackTracking() {
12016 DCHECK(has_initial_map());
12017 initial_map()->CompleteInobjectSlackTracking();
12018 }
12019
12020
12021 void Map::CompleteInobjectSlackTracking() { 12028 void Map::CompleteInobjectSlackTracking() {
12022 // Has to be an initial map. 12029 // Has to be an initial map.
12023 DCHECK(GetBackPointer()->IsUndefined()); 12030 DCHECK(GetBackPointer()->IsUndefined());
12024 12031
12025 DCHECK_GE(counter(), kSlackTrackingCounterEnd - 1); 12032 DCHECK_GE(counter(), kSlackTrackingCounterEnd - 1);
12026 set_counter(kRetainingCounterStart); 12033 set_counter(kRetainingCounterStart);
12027 12034
12028 int slack = unused_property_fields(); 12035 int slack = unused_property_fields();
12029 TransitionArray::TraverseTransitionTree(this, &GetMinInobjectSlack, &slack); 12036 TransitionArray::TraverseTransitionTree(this, &GetMinInobjectSlack, &slack);
12030 if (slack != 0) { 12037 if (slack != 0) {
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
12329 12336
12330 DCHECK(value->IsJSReceiver()); 12337 DCHECK(value->IsJSReceiver());
12331 12338
12332 // Now some logic for the maps of the objects that are created by using this 12339 // Now some logic for the maps of the objects that are created by using this
12333 // function as a constructor. 12340 // function as a constructor.
12334 if (function->has_initial_map()) { 12341 if (function->has_initial_map()) {
12335 // If the function has allocated the initial map replace it with a 12342 // If the function has allocated the initial map replace it with a
12336 // copy containing the new prototype. Also complete any in-object 12343 // copy containing the new prototype. Also complete any in-object
12337 // slack tracking that is in progress at this point because it is 12344 // slack tracking that is in progress at this point because it is
12338 // still tracking the old copy. 12345 // still tracking the old copy.
12339 if (function->IsInobjectSlackTrackingInProgress()) { 12346 function->CompleteInobjectSlackTrackingIfActive();
12340 function->CompleteInobjectSlackTracking();
12341 }
12342 12347
12343 Handle<Map> initial_map(function->initial_map(), isolate); 12348 Handle<Map> initial_map(function->initial_map(), isolate);
12344 12349
12345 if (!initial_map->GetIsolate()->bootstrapper()->IsActive() && 12350 if (!initial_map->GetIsolate()->bootstrapper()->IsActive() &&
12346 initial_map->instance_type() == JS_OBJECT_TYPE) { 12351 initial_map->instance_type() == JS_OBJECT_TYPE) {
12347 // Put the value in the initial map field until an initial map is needed. 12352 // Put the value in the initial map field until an initial map is needed.
12348 // At that point, a new initial map is created and the prototype is put 12353 // At that point, a new initial map is created and the prototype is put
12349 // into the initial map where it belongs. 12354 // into the initial map where it belongs.
12350 function->set_prototype_or_initial_map(*value); 12355 function->set_prototype_or_initial_map(*value);
12351 } else { 12356 } else {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
12561 } else { 12566 } else {
12562 prototype = isolate->factory()->NewFunctionPrototype(function); 12567 prototype = isolate->factory()->NewFunctionPrototype(function);
12563 } 12568 }
12564 map->SetInObjectProperties(in_object_properties); 12569 map->SetInObjectProperties(in_object_properties);
12565 map->set_unused_property_fields(in_object_properties); 12570 map->set_unused_property_fields(in_object_properties);
12566 DCHECK(map->has_fast_object_elements()); 12571 DCHECK(map->has_fast_object_elements());
12567 12572
12568 // Finally link initial map and constructor function. 12573 // Finally link initial map and constructor function.
12569 DCHECK(prototype->IsJSReceiver()); 12574 DCHECK(prototype->IsJSReceiver());
12570 JSFunction::SetInitialMap(function, map, prototype); 12575 JSFunction::SetInitialMap(function, map, prototype);
12571 12576 map->StartInobjectSlackTracking();
12572 if (!function->shared()->is_generator()) {
12573 function->StartInobjectSlackTracking();
12574 }
12575 } 12577 }
12576 12578
12577 12579
12578 // static 12580 // static
12579 MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate, 12581 MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
12580 Handle<JSFunction> constructor, 12582 Handle<JSFunction> constructor,
12581 Handle<JSReceiver> new_target) { 12583 Handle<JSReceiver> new_target) {
12582 EnsureHasInitialMap(constructor); 12584 EnsureHasInitialMap(constructor);
12583 12585
12584 Handle<Map> constructor_initial_map(constructor->initial_map(), isolate); 12586 Handle<Map> constructor_initial_map(constructor->initial_map(), isolate);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
12639 new_target_function->CalculateInstanceSizeForDerivedClass( 12641 new_target_function->CalculateInstanceSizeForDerivedClass(
12640 instance_type, internal_fields, &instance_size, &in_object_properties); 12642 instance_type, internal_fields, &instance_size, &in_object_properties);
12641 12643
12642 int unused_property_fields = in_object_properties - pre_allocated; 12644 int unused_property_fields = in_object_properties - pre_allocated;
12643 Handle<Map> map = 12645 Handle<Map> map =
12644 Map::CopyInitialMap(constructor_initial_map, instance_size, 12646 Map::CopyInitialMap(constructor_initial_map, instance_size,
12645 in_object_properties, unused_property_fields); 12647 in_object_properties, unused_property_fields);
12646 12648
12647 JSFunction::SetInitialMap(new_target_function, map, prototype); 12649 JSFunction::SetInitialMap(new_target_function, map, prototype);
12648 map->SetConstructor(*constructor); 12650 map->SetConstructor(*constructor);
12649 new_target_function->StartInobjectSlackTracking(); 12651 map->StartInobjectSlackTracking();
12650 return map; 12652 return map;
12651 } 12653 }
12652 12654
12653 // Fetch the prototype. 12655 // Fetch the prototype.
12654 Handle<Object> prototype; 12656 Handle<Object> prototype;
12655 if (new_target_function->map()->has_non_instance_prototype()) { 12657 if (new_target_function->map()->has_non_instance_prototype()) {
12656 // TODO(verwaest): In case of non-instance prototype, use the 12658 // TODO(verwaest): In case of non-instance prototype, use the
12657 // intrinsicDefaultProto instead. 12659 // intrinsicDefaultProto instead.
12658 prototype = handle(new_target_function->context() 12660 prototype = handle(new_target_function->context()
12659 ->native_context() 12661 ->native_context()
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
13191 DCHECK(!id.IsNone()); 13193 DCHECK(!id.IsNone());
13192 Code* unoptimized = code(); 13194 Code* unoptimized = code();
13193 DeoptimizationOutputData* data = 13195 DeoptimizationOutputData* data =
13194 DeoptimizationOutputData::cast(unoptimized->deoptimization_data()); 13196 DeoptimizationOutputData::cast(unoptimized->deoptimization_data());
13195 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this); 13197 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this);
13196 USE(ignore); 13198 USE(ignore);
13197 return true; // Return true if there was no DCHECK. 13199 return true; // Return true if there was no DCHECK.
13198 } 13200 }
13199 13201
13200 13202
13201 void JSFunction::StartInobjectSlackTracking() { 13203 void Map::StartInobjectSlackTracking() {
13202 DCHECK(has_initial_map() && !IsInobjectSlackTrackingInProgress()); 13204 DCHECK(!IsInobjectSlackTrackingInProgress());
13203
13204 Map* map = initial_map();
13205 13205
13206 // No tracking during the snapshot construction phase. 13206 // No tracking during the snapshot construction phase.
13207 Isolate* isolate = GetIsolate(); 13207 Isolate* isolate = GetIsolate();
13208 if (isolate->serializer_enabled()) return; 13208 if (isolate->serializer_enabled()) return;
13209 13209
13210 if (map->unused_property_fields() == 0) return; 13210 if (unused_property_fields() == 0) return;
13211 13211
13212 map->set_counter(Map::kSlackTrackingCounterStart); 13212 set_counter(Map::kSlackTrackingCounterStart);
13213 } 13213 }
13214 13214
13215 13215
13216 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { 13216 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) {
13217 code()->ClearInlineCaches(); 13217 code()->ClearInlineCaches();
13218 // If we clear ICs, we need to clear the type feedback vector too, since 13218 // If we clear ICs, we need to clear the type feedback vector too, since
13219 // CallICs are synced with a feedback vector slot. 13219 // CallICs are synced with a feedback vector slot.
13220 ClearTypeFeedbackInfo(); 13220 ClearTypeFeedbackInfo();
13221 set_ic_age(new_ic_age); 13221 set_ic_age(new_ic_age);
13222 if (code()->kind() == Code::FUNCTION) { 13222 if (code()->kind() == Code::FUNCTION) {
(...skipping 5786 matching lines...) Expand 10 before | Expand all | Expand 10 after
19009 if (cell->value() != *new_value) { 19009 if (cell->value() != *new_value) {
19010 cell->set_value(*new_value); 19010 cell->set_value(*new_value);
19011 Isolate* isolate = cell->GetIsolate(); 19011 Isolate* isolate = cell->GetIsolate();
19012 cell->dependent_code()->DeoptimizeDependentCodeGroup( 19012 cell->dependent_code()->DeoptimizeDependentCodeGroup(
19013 isolate, DependentCode::kPropertyCellChangedGroup); 19013 isolate, DependentCode::kPropertyCellChangedGroup);
19014 } 19014 }
19015 } 19015 }
19016 19016
19017 } // namespace internal 19017 } // namespace internal
19018 } // namespace v8 19018 } // namespace v8
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