| 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 |