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 "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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |