From: jarin@chromium.org Date: Mon, 14 Apr 2014 08:24:15 +0000 (+0000) Subject: Revert "Track field types." X-Git-Tag: upstream/4.7.83~9659 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c1a3ab6b4f85f22e87d2f6afaeecea57e668c6ba;p=platform%2Fupstream%2Fv8.git Revert "Track field types." Revert r20701. TBR=bmeurer@chromium.org BUG= Review URL: https://codereview.chromium.org/236843002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20704 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 8294b18..34d98b7 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -4111,7 +4111,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { __ SmiTst(value); DeoptimizeIf(eq, instr->environment()); - // We know now that value is not a smi, so we can omit the check below. + // We know that value is a smi now, so we can omit the check below. check_needed = OMIT_SMI_CHECK; } } else if (representation.IsDouble()) { diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index ebbfce6..c595e42 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -430,14 +430,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, } else if (representation.IsSmi()) { __ JumpIfNotSmi(value_reg, miss_label); } else if (representation.IsHeapObject()) { - HeapType* field_type = descriptors->GetFieldType(descriptor); - if (field_type->IsClass()) { - __ CheckMap(value_reg, scratch1, field_type->AsClass(), - miss_label, DO_SMI_CHECK); - } else { - ASSERT(HeapType::Any()->Is(field_type)); - __ JumpIfSmi(value_reg, miss_label); - } + __ JumpIfSmi(value_reg, miss_label); } else if (representation.IsDouble()) { Label do_store, heap_number; __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); @@ -599,14 +592,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, if (representation.IsSmi()) { __ JumpIfNotSmi(value_reg, miss_label); } else if (representation.IsHeapObject()) { - HeapType* field_type = lookup->GetFieldType(); - if (field_type->IsClass()) { - __ CheckMap(value_reg, scratch1, field_type->AsClass(), - miss_label, DO_SMI_CHECK); - } else { - ASSERT(HeapType::Any()->Is(field_type)); - __ JumpIfSmi(value_reg, miss_label); - } + __ JumpIfSmi(value_reg, miss_label); } else if (representation.IsDouble()) { // Load the double storage. if (index < 0) { diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index e0648c3..99f3b27 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -5265,7 +5265,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { !instr->hydrogen()->value()->type().IsHeapObject()) { DeoptimizeIfSmi(value, instr->environment()); - // We know now that value is not a smi, so we can omit the check below. + // We know that value is a smi now, so we can omit the check below. check_needed = OMIT_SMI_CHECK; } diff --git a/src/arm64/stub-cache-arm64.cc b/src/arm64/stub-cache-arm64.cc index e5383f1..aed9af9 100644 --- a/src/arm64/stub-cache-arm64.cc +++ b/src/arm64/stub-cache-arm64.cc @@ -392,14 +392,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, } else if (representation.IsSmi()) { __ JumpIfNotSmi(value_reg, miss_label); } else if (representation.IsHeapObject()) { - HeapType* field_type = descriptors->GetFieldType(descriptor); - if (field_type->IsClass()) { - __ CheckMap(value_reg, scratch1, field_type->AsClass(), - miss_label, DO_SMI_CHECK); - } else { - ASSERT(HeapType::Any()->Is(field_type)); - __ JumpIfSmi(value_reg, miss_label); - } + __ JumpIfSmi(value_reg, miss_label); } else if (representation.IsDouble()) { UseScratchRegisterScope temps(masm); DoubleRegister temp_double = temps.AcquireD(); @@ -548,14 +541,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, if (representation.IsSmi()) { __ JumpIfNotSmi(value_reg, miss_label); } else if (representation.IsHeapObject()) { - HeapType* field_type = lookup->GetFieldType(); - if (field_type->IsClass()) { - __ CheckMap(value_reg, scratch1, field_type->AsClass(), - miss_label, DO_SMI_CHECK); - } else { - ASSERT(HeapType::Any()->Is(field_type)); - __ JumpIfSmi(value_reg, miss_label); - } + __ JumpIfSmi(value_reg, miss_label); } else if (representation.IsDouble()) { UseScratchRegisterScope temps(masm); DoubleRegister temp_double = temps.AcquireD(); diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index e2fa5f3..4d5e605 100644 --- a/src/deoptimizer.cc +++ b/src/deoptimizer.cc @@ -1840,7 +1840,7 @@ Handle Deoptimizer::MaterializeNextHeapObject() { // We also need to make sure that the representation of all fields // in the given object are general enough to hold a tagged value. Handle map = Map::GeneralizeAllFieldRepresentations( - Handle::cast(MaterializeNextValue())); + Handle::cast(MaterializeNextValue()), Representation::Tagged()); switch (map->instance_type()) { case HEAP_NUMBER_TYPE: { // Reuse the HeapNumber value directly as it is already properly @@ -3341,7 +3341,7 @@ Handle SlotRefValueBuilder::GetNext(Isolate* isolate, int lvl) { Handle map_object = slot_refs_[current_slot_].GetValue(isolate); Handle map = Map::GeneralizeAllFieldRepresentations( - Handle::cast(map_object)); + Handle::cast(map_object), Representation::Tagged()); current_slot_++; // TODO(jarin) this should be unified with the code in // Deoptimizer::MaterializeNextHeapObject() diff --git a/src/flag-definitions.h b/src/flag-definitions.h index 989e285..1942c35 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -233,9 +233,6 @@ DEFINE_bool(track_computed_fields, true, "track computed boilerplate fields") DEFINE_implication(track_double_fields, track_fields) DEFINE_implication(track_heap_object_fields, track_fields) DEFINE_implication(track_computed_fields, track_fields) -DEFINE_bool(track_field_types, true, "track field types") -DEFINE_implication(track_field_types, track_fields) -DEFINE_implication(track_field_types, track_heap_object_fields) DEFINE_bool(smi_binop, true, "support smi representation in binary operations") // Flags for optimization types. diff --git a/src/heap.cc b/src/heap.cc index d521ddc..00e513b 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -5476,7 +5476,6 @@ bool Heap::InSpace(Address addr, AllocationSpace space) { #ifdef VERIFY_HEAP void Heap::Verify() { CHECK(HasBeenSetUp()); - HandleScope scope(isolate()); store_buffer()->Verify(); diff --git a/src/hydrogen-check-elimination.cc b/src/hydrogen-check-elimination.cc index 4fd769f..52a5492 100644 --- a/src/hydrogen-check-elimination.cc +++ b/src/hydrogen-check-elimination.cc @@ -382,13 +382,7 @@ class HCheckTable : public ZoneObject { void ReduceLoadNamedField(HLoadNamedField* instr) { // Reduce a load of the map field when it is known to be a constant. - if (!IsMapAccess(instr->access())) { - // Check if we introduce a map here. - if (!instr->map().IsNull()) { - Insert(instr, instr, instr->map()); - } - return; - } + if (!IsMapAccess(instr->access())) return; HValue* object = instr->object()->ActualValue(); MapSet maps = FindMaps(object); diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index a9bfd47..336c9f7 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -3382,10 +3382,6 @@ void HLoadNamedField::PrintDataTo(StringStream* stream) { object()->PrintNameTo(stream); access_.PrintTo(stream); - if (!map().IsNull()) { - stream->Add(" (%p)", *map().handle()); - } - if (HasDependency()) { stream->Add(" "); dependency()->PrintNameTo(stream); diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 4a2bf10..26501d0 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -6144,8 +6144,6 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> { public: DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HValue*, HObjectAccess); - DECLARE_INSTRUCTION_FACTORY_P4(HLoadNamedField, HValue*, HValue*, - HObjectAccess, Handle); HValue* object() { return OperandAt(0); } HValue* dependency() { @@ -6158,8 +6156,6 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> { return access_.representation(); } - Unique map() const { return map_; } - virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { return !access().IsInobject() || access().offset() >= size; @@ -6179,15 +6175,13 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> { protected: virtual bool DataEquals(HValue* other) V8_OVERRIDE { HLoadNamedField* b = HLoadNamedField::cast(other); - return access_.Equals(b->access_) && map_ == b->map_; + return access_.Equals(b->access_); } private: HLoadNamedField(HValue* object, HValue* dependency, - HObjectAccess access, - Handle map = Handle::null()) - : access_(access), map_(map) { + HObjectAccess access) : access_(access) { ASSERT(object != NULL); SetOperandAt(0, object); SetOperandAt(1, dependency != NULL ? dependency : object); @@ -6221,7 +6215,6 @@ class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> { virtual bool IsDeletable() const V8_OVERRIDE { return true; } HObjectAccess access_; - Unique map_; }; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index c5d4577..cf34517 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -5370,7 +5370,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField( access = HObjectAccess::ForHeapNumberValue(); } return New( - checked_object, static_cast(NULL), access, info->field_map()); + checked_object, static_cast(NULL), access); } @@ -5415,12 +5415,6 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( value, STORE_TO_INITIALIZED_ENTRY); } } else { - if (!info->field_map().is_null()) { - ASSERT(field_access.representation().IsHeapObject()); - BuildCheckHeapObject(value); - value = BuildCheckMap(value, info->field_map()); - } - // This is a normal store. instr = New( checked_object->ActualValue(), field_access, value, @@ -5484,12 +5478,6 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( } if (info->access_.offset() != access_.offset()) return false; if (info->access_.IsInobject() != access_.IsInobject()) return false; - if (!field_map_.is_identical_to(info->field_map_)) { - if (!IsLoad()) return false; - - // Throw away type information for merging polymorphic loads. - field_map_ = info->field_map_ = Handle(); - } info->GeneralizeRepresentation(r); return true; } @@ -5509,26 +5497,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle map) { } if (lookup_.IsField()) { - // Construct the object field access. access_ = HObjectAccess::ForField(map, &lookup_, name_); - - if (access_.representation().IsHeapObject()) { - // Figure out the field type from the accessor map. - HeapType* field_type = lookup_.GetFieldTypeFromMap(*map); - if (field_type->IsClass()) { - Handle field_map = field_type->AsClass(); - if (field_map->is_stable()) { // TODO(bmeurer) - field_map_ = field_map; - field_map_->AddDependentCompilationInfo( - DependentCode::kPrototypeCheckGroup, top_info()); - - // Add dependency on the map that introduced the field. - Handle field_owner = handle(lookup_.GetFieldOwnerFromMap(*map)); - field_owner->AddDependentCompilationInfo( - DependentCode::kFieldTypeGroup, top_info()); - } - } - } } else if (lookup_.IsPropertyCallbacks()) { Handle callback(lookup_.GetValueFromMap(*map), isolate()); if (!callback->IsAccessorPair()) return false; diff --git a/src/hydrogen.h b/src/hydrogen.h index 5a1ef85..ac6b99d 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -2414,13 +2414,11 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { Handle accessor() { return accessor_; } Handle constant() { return constant_; } Handle transition() { return handle(lookup_.GetTransitionTarget()); } - Handle field_map() { return field_map_; } HObjectAccess access() { return access_; } private: Type* ToType(Handle map) { return builder_->ToType(map); } Isolate* isolate() { return lookup_.isolate(); } - CompilationInfo* top_info() { return builder_->top_info(); } CompilationInfo* current_info() { return builder_->current_info(); } bool LoadResult(Handle map); @@ -2442,7 +2440,6 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { Handle accessor_; Handle api_holder_; Handle constant_; - Handle field_map_; HObjectAccess access_; }; diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index fad23ad..ebd430c 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -4406,7 +4406,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { __ test(value, Immediate(kSmiTagMask)); DeoptimizeIf(zero, instr->environment()); - // We know now that value is not a smi, so we can omit the check below. + // We know that value is a smi now, so we can omit the check below. check_needed = OMIT_SMI_CHECK; } } diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 209bfa6..1a745c7 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -528,13 +528,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, } else if (representation.IsSmi()) { __ JumpIfNotSmi(value_reg, miss_label); } else if (representation.IsHeapObject()) { - HeapType* field_type = descriptors->GetFieldType(descriptor); - if (field_type->IsClass()) { - __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK); - } else { - ASSERT(HeapType::Any()->Is(field_type)); - __ JumpIfSmi(value_reg, miss_label); - } + __ JumpIfSmi(value_reg, miss_label); } else if (representation.IsDouble()) { Label do_store, heap_number; __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow); @@ -704,13 +698,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, if (representation.IsSmi()) { __ JumpIfNotSmi(value_reg, miss_label); } else if (representation.IsHeapObject()) { - HeapType* field_type = lookup->GetFieldType(); - if (field_type->IsClass()) { - __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK); - } else { - ASSERT(HeapType::Any()->Is(field_type)); - __ JumpIfSmi(value_reg, miss_label); - } + __ JumpIfSmi(value_reg, miss_label); } else if (representation.IsDouble()) { // Load the double storage. if (index < 0) { diff --git a/src/ic.cc b/src/ic.cc index 1f1dc1f..a5936c6 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -1218,12 +1218,9 @@ static bool LookupForWrite(Handle receiver, ASSERT(!receiver->map()->is_deprecated()); if (!lookup->CanHoldValue(value)) { Handle target(lookup->GetTransitionTarget()); - Representation field_representation = value->OptimalRepresentation(); - Handle field_type = value->OptimalType( - lookup->isolate(), field_representation); Map::GeneralizeRepresentation( target, target->LastAdded(), - field_representation, field_type, FORCE_FIELD); + value->OptimalRepresentation(), FORCE_FIELD); // Lookup the transition again since the transition tree may have changed // entirely by the migration above. receiver->map()->LookupTransition(*holder, *name, lookup); diff --git a/src/json-parser.h b/src/json-parser.h index 8c19bc8..a7dbd3a 100644 --- a/src/json-parser.h +++ b/src/json-parser.h @@ -415,15 +415,7 @@ Handle JsonParser::ParseJsonObject() { if (value->IsSmi() && expected_representation.IsDouble()) { value = factory()->NewHeapNumber( Handle::cast(value)->value()); - } else if (expected_representation.IsHeapObject() && - !target->instance_descriptors()->GetFieldType( - descriptor)->NowContains(value)) { - Handle value_type(value->OptimalType( - isolate(), expected_representation)); - Map::GeneralizeFieldType(target, descriptor, value_type); } - ASSERT(target->instance_descriptors()->GetFieldType( - descriptor)->NowContains(value)); properties.Add(value, zone()); map = target; continue; diff --git a/src/objects-debug.cc b/src/objects-debug.cc index 2ff7058..bacf422 100644 --- a/src/objects-debug.cc +++ b/src/objects-debug.cc @@ -299,15 +299,6 @@ void JSObject::JSObjectVerify() { if (value->IsUninitialized()) continue; if (r.IsSmi()) ASSERT(value->IsSmi()); if (r.IsHeapObject()) ASSERT(value->IsHeapObject()); - HeapType* field_type = descriptors->GetFieldType(i); - if (field_type->IsClass()) { - Map* map = *field_type->AsClass(); - CHECK(!map->is_stable() || HeapObject::cast(value)->map() == map); - } else if (r.IsNone()) { - CHECK(field_type->Is(HeapType::None())); - } else { - CHECK(HeapType::Any()->Is(field_type)); - } } } } diff --git a/src/objects-inl.h b/src/objects-inl.h index 2c89a14..ed66dc6 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -286,7 +286,6 @@ bool Object::IsExternalTwoByteString() { String::cast(this)->IsTwoByteRepresentation(); } - bool Object::HasValidElements() { // Dictionary is covered under FixedArray. return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray() || @@ -2724,6 +2723,14 @@ void DescriptorArray::SetRepresentation(int descriptor_index, } +void DescriptorArray::InitializeRepresentations(Representation representation) { + int length = number_of_descriptors(); + for (int i = 0; i < length; i++) { + SetRepresentation(i, representation); + } +} + + Object** DescriptorArray::GetValueSlot(int descriptor_number) { ASSERT(descriptor_number < number_of_descriptors()); return RawFieldOfElementAt(ToValueIndex(descriptor_number)); @@ -2736,11 +2743,6 @@ Object* DescriptorArray::GetValue(int descriptor_number) { } -void DescriptorArray::SetValue(int descriptor_index, Object* value) { - set(ToValueIndex(descriptor_index), value); -} - - PropertyDetails DescriptorArray::GetDetails(int descriptor_number) { ASSERT(descriptor_number < number_of_descriptors()); Object* details = get(ToDetailsIndex(descriptor_number)); @@ -2759,12 +2761,6 @@ int DescriptorArray::GetFieldIndex(int descriptor_number) { } -HeapType* DescriptorArray::GetFieldType(int descriptor_number) { - ASSERT(GetDetails(descriptor_number).type() == FIELD); - return HeapType::cast(GetValue(descriptor_number)); -} - - Object* DescriptorArray::GetConstant(int descriptor_number) { return GetValue(descriptor_number); } diff --git a/src/objects.cc b/src/objects.cc index dae7d51..aaa0320 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -73,23 +73,6 @@ MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, } -Handle Object::OptimalType(Isolate* isolate, - Representation representation) { - if (!FLAG_track_field_types) return HeapType::Any(isolate); - if (representation.IsNone()) return HeapType::None(isolate); - if (representation.IsHeapObject() && IsHeapObject()) { - // We can track only JavaScript objects with stable maps. - Handle map(HeapObject::cast(this)->map(), isolate); - if (map->is_stable() && - map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE && - map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) { - return HeapType::Class(map, isolate); - } - } - return HeapType::Any(isolate); -} - - MaybeObject* Object::ToObject(Context* native_context) { if (IsNumber()) { return CreateJSValue(native_context->number_function(), this); @@ -1464,9 +1447,7 @@ void Map::PrintGeneralization(FILE* file, int descriptors, bool constant_to_field, Representation old_representation, - Representation new_representation, - HeapType* old_field_type, - HeapType* new_field_type) { + Representation new_representation) { PrintF(file, "[generalizing "); constructor_name()->PrintOn(file); PrintF(file, "] "); @@ -1476,19 +1457,13 @@ void Map::PrintGeneralization(FILE* file, } else { PrintF(file, "{symbol %p}", static_cast(name)); } - PrintF(file, ":"); if (constant_to_field) { - PrintF(file, "c"); + PrintF(file, ":c->f"); } else { - PrintF(file, "%s", old_representation.Mnemonic()); - PrintF(file, "{"); - old_field_type->TypePrint(file, HeapType::SEMANTIC_DIM); - PrintF(file, "}"); - } - PrintF(file, "->%s", new_representation.Mnemonic()); - PrintF(file, "{"); - new_field_type->TypePrint(file, HeapType::SEMANTIC_DIM); - PrintF(file, "}"); + PrintF(file, ":%s->%s", + old_representation.Mnemonic(), + new_representation.Mnemonic()); + } PrintF(file, " ("); if (strlen(reason) > 0) { PrintF(file, "%s", reason); @@ -1880,12 +1855,10 @@ static Handle NewStorageFor(Isolate* isolate, static Handle CopyAddFieldDescriptor(Handle map, Handle name, int index, - Handle field_type, PropertyAttributes attributes, Representation representation, TransitionFlag flag) { - FieldDescriptor new_field_desc(name, index, field_type, - attributes, representation); + FieldDescriptor new_field_desc(name, index, attributes, representation); Handle new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); int unused_property_fields = map->unused_property_fields() - 1; if (unused_property_fields < 0) { @@ -1922,14 +1895,11 @@ void JSObject::AddFastProperty(Handle object, // Compute the new index for new field. int index = object->map()->NextFreePropertyIndex(); - // Compute the optimal representation for the new field. + // Allocate new instance descriptors with (name, index) added if (object->IsJSContextExtensionObject()) value_type = FORCE_TAGGED; Representation representation = value->OptimalRepresentation(value_type); - Handle new_map = CopyAddFieldDescriptor( - handle(object->map()), name, index, - value->OptimalType(isolate, representation), - attributes, representation, flag); + handle(object->map()), name, index, attributes, representation, flag); JSObject::MigrateToMap(object, new_map); @@ -2375,11 +2345,9 @@ void JSObject::MigrateToMap(Handle object, Handle new_map) { void JSObject::GeneralizeFieldRepresentation(Handle object, int modify_index, Representation new_representation, - Handle new_field_type, StoreMode store_mode) { Handle new_map = Map::GeneralizeRepresentation( - handle(object->map()), modify_index, new_representation, - new_field_type, store_mode); + handle(object->map()), modify_index, new_representation, store_mode); if (object->map() == *new_map) return; return MigrateToMap(object, new_map); } @@ -2400,22 +2368,16 @@ Handle Map::CopyGeneralizeAllRepresentations(Handle map, StoreMode store_mode, PropertyAttributes attributes, const char* reason) { - Isolate* isolate = map->GetIsolate(); Handle new_map = Copy(map); DescriptorArray* descriptors = new_map->instance_descriptors(); - int length = descriptors->number_of_descriptors(); - for (int i = 0; i < length; i++) { - descriptors->SetRepresentation(i, Representation::Tagged()); - if (descriptors->GetDetails(i).type() == FIELD) { - descriptors->SetValue(i, HeapType::Any()); - } - } + descriptors->InitializeRepresentations(Representation::Tagged()); // Unless the instance is being migrated, ensure that modify_index is a field. PropertyDetails details = descriptors->GetDetails(modify_index); if (store_mode == FORCE_FIELD && details.type() != FIELD) { - FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), + FieldDescriptor d(handle(descriptors->GetKey(modify_index), + map->GetIsolate()), new_map->NumberOfFields(), attributes, Representation::Tagged()); @@ -2428,15 +2390,11 @@ Handle Map::CopyGeneralizeAllRepresentations(Handle map, } if (FLAG_trace_generalization) { - HeapType* field_type = (details.type() == FIELD) - ? map->instance_descriptors()->GetFieldType(modify_index) - : NULL; map->PrintGeneralization(stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), new_map->NumberOfOwnDescriptors(), details.type() == CONSTANT && store_mode == FORCE_FIELD, - details.representation(), Representation::Tagged(), - field_type, HeapType::Any()); + Representation::Tagged(), Representation::Tagged()); } return new_map; } @@ -2501,8 +2459,6 @@ Map* Map::FindRootMap() { Map* Map::FindUpdatedMap(int verbatim, int length, DescriptorArray* descriptors) { - DisallowHeapAllocation no_allocation; - // This can only be called on roots of transition trees. ASSERT(GetBackPointer()->IsUndefined()); @@ -2537,8 +2493,6 @@ Map* Map::FindUpdatedMap(int verbatim, Map* Map::FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors) { - DisallowHeapAllocation no_allocation; - // This can only be called on roots of transition trees. ASSERT(GetBackPointer()->IsUndefined()); @@ -2554,17 +2508,13 @@ Map* Map::FindLastMatchMap(int verbatim, Map* next = transitions->GetTarget(transition); DescriptorArray* next_descriptors = next->instance_descriptors(); + if (next_descriptors->GetValue(i) != descriptors->GetValue(i)) break; + PropertyDetails details = descriptors->GetDetails(i); PropertyDetails next_details = next_descriptors->GetDetails(i); if (details.type() != next_details.type()) break; if (details.attributes() != next_details.attributes()) break; if (!details.representation().Equals(next_details.representation())) break; - if (next_details.type() == FIELD) { - if (!descriptors->GetFieldType(i)->NowIs( - next_descriptors->GetFieldType(i))) break; - } else { - if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; - } current = next; } @@ -2572,87 +2522,6 @@ Map* Map::FindLastMatchMap(int verbatim, } -Map* Map::FindFieldOwner(int descriptor) { - DisallowHeapAllocation no_allocation; - ASSERT_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type()); - Map* result = this; - while (true) { - Object* back = result->GetBackPointer(); - if (back->IsUndefined()) break; - Map* parent = Map::cast(back); - if (parent->NumberOfOwnDescriptors() <= descriptor) break; - result = parent; - } - return result; -} - - -void Map::UpdateDescriptor(int descriptor_number, Descriptor* desc) { - DisallowHeapAllocation no_allocation; - if (HasTransitionArray()) { - TransitionArray* transitions = this->transitions(); - for (int i = 0; i < transitions->number_of_transitions(); ++i) { - transitions->GetTarget(i)->UpdateDescriptor(descriptor_number, desc); - } - } - instance_descriptors()->Replace(descriptor_number, desc);; -} - - -// static -Handle Map::GeneralizeFieldType(Handle old_field_type, - Handle new_field_type, - Isolate* isolate) { - if (new_field_type->NowIs(old_field_type)) return old_field_type; - if (old_field_type->NowIs(new_field_type)) return new_field_type; - return HeapType::Any(isolate); -} - - -// static -void Map::GeneralizeFieldType(Handle map, - int modify_index, - Handle new_field_type) { - Isolate* isolate = map->GetIsolate(); - Handle field_owner(map->FindFieldOwner(modify_index), isolate); - Handle descriptors( - field_owner->instance_descriptors(), isolate); - - // Check if we actually need to generalize the field type at all. - Handle old_field_type( - descriptors->GetFieldType(modify_index), isolate); - if (new_field_type->NowIs(old_field_type)) { - ASSERT(Map::GeneralizeFieldType(old_field_type, - new_field_type, - isolate)->NowIs(old_field_type)); - return; - } - - // Determine the generalized new field type. - new_field_type = Map::GeneralizeFieldType( - old_field_type, new_field_type, isolate); - - PropertyDetails details = descriptors->GetDetails(modify_index); - FieldDescriptor d(handle(descriptors->GetKey(modify_index), isolate), - descriptors->GetFieldIndex(modify_index), - new_field_type, - details.attributes(), - details.representation()); - field_owner->UpdateDescriptor(modify_index, &d); - field_owner->dependent_code()->DeoptimizeDependentCodeGroup( - isolate, DependentCode::kFieldTypeGroup); - - if (FLAG_trace_generalization) { - map->PrintGeneralization( - stdout, "field type generalization", - modify_index, map->NumberOfOwnDescriptors(), - map->NumberOfOwnDescriptors(), false, - details.representation(), details.representation(), - *old_field_type, *new_field_type); - } -} - - // Generalize the representation of the descriptor at |modify_index|. // This method rewrites the transition tree to reflect the new change. To avoid // high degrees over polymorphism, and to stabilize quickly, on every rewrite @@ -2674,7 +2543,6 @@ void Map::GeneralizeFieldType(Handle map, Handle Map::GeneralizeRepresentation(Handle old_map, int modify_index, Representation new_representation, - Handle new_field_type, StoreMode store_mode) { Handle old_descriptors(old_map->instance_descriptors()); PropertyDetails old_details = old_descriptors->GetDetails(modify_index); @@ -2687,28 +2555,11 @@ Handle Map::GeneralizeRepresentation(Handle old_map, if (old_representation.IsNone() && !new_representation.IsNone() && !new_representation.IsDouble()) { - ASSERT(old_details.type() == FIELD); - ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs( - HeapType::None())); - if (FLAG_trace_generalization) { - old_map->PrintGeneralization( - stdout, "uninitialized field", - modify_index, old_map->NumberOfOwnDescriptors(), - old_map->NumberOfOwnDescriptors(), false, - old_representation, new_representation, - old_descriptors->GetFieldType(modify_index), *new_field_type); - } old_descriptors->SetRepresentation(modify_index, new_representation); - old_descriptors->SetValue(modify_index, *new_field_type); - return old_map; - } - - if (new_representation.Equals(old_representation) && - old_details.type() == FIELD) { - Map::GeneralizeFieldType(old_map, modify_index, new_field_type); return old_map; } + int descriptors = old_map->NumberOfOwnDescriptors(); Handle root_map(old_map->FindRootMap()); // Check the state of the root map. @@ -2724,7 +2575,6 @@ Handle Map::GeneralizeRepresentation(Handle old_map, old_details.attributes(), "root modification"); } - int descriptors = old_map->NumberOfOwnDescriptors(); Map* raw_updated = root_map->FindUpdatedMap( verbatim, descriptors, *old_descriptors); if (raw_updated == NULL) { @@ -2754,7 +2604,6 @@ Handle Map::GeneralizeRepresentation(Handle old_map, ASSERT(store_mode == ALLOW_AS_CONSTANT || new_descriptors->GetDetails(modify_index).type() == FIELD); - Isolate* isolate = new_descriptors->GetIsolate(); old_representation = new_descriptors->GetDetails(modify_index).representation(); Representation updated_representation = @@ -2762,13 +2611,6 @@ Handle Map::GeneralizeRepresentation(Handle old_map, if (!updated_representation.Equals(old_representation)) { new_descriptors->SetRepresentation(modify_index, updated_representation); } - if (new_descriptors->GetDetails(modify_index).type() == FIELD) { - Handle field_type( - new_descriptors->GetFieldType(modify_index), isolate); - new_field_type = Map::GeneralizeFieldType( - field_type, new_field_type, isolate); - new_descriptors->SetValue(modify_index, *new_field_type); - } Handle split_map(root_map->FindLastMatchMap( verbatim, descriptors, *new_descriptors)); @@ -2783,21 +2625,11 @@ Handle Map::GeneralizeRepresentation(Handle old_map, old_descriptors->GetKey(descriptor), *new_descriptors); if (FLAG_trace_generalization) { - PropertyDetails old_details = old_descriptors->GetDetails(modify_index); - PropertyDetails new_details = new_descriptors->GetDetails(modify_index); - Handle old_field_type = (old_details.type() == FIELD) - ? handle(old_descriptors->GetFieldType(modify_index), isolate) - : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), - isolate), isolate); - Handle new_field_type = (new_details.type() == FIELD) - ? handle(new_descriptors->GetFieldType(modify_index), isolate) - : HeapType::Constant(handle(new_descriptors->GetValue(modify_index), - isolate), isolate); old_map->PrintGeneralization( stdout, "", modify_index, descriptor, descriptors, - old_details.type() == CONSTANT && store_mode == FORCE_FIELD, - old_details.representation(), new_details.representation(), - *old_field_type, *new_field_type); + old_descriptors->GetDetails(modify_index).type() == CONSTANT && + store_mode == FORCE_FIELD, + old_representation, updated_representation); } // Add missing transitions. @@ -2813,13 +2645,13 @@ Handle Map::GeneralizeRepresentation(Handle old_map, // Generalize the representation of all FIELD descriptors. Handle Map::GeneralizeAllFieldRepresentations( - Handle map) { + Handle map, + Representation new_representation) { Handle descriptors(map->instance_descriptors()); - for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { - if (descriptors->GetDetails(i).type() == FIELD) { - map = GeneralizeRepresentation(map, i, Representation::Tagged(), - HeapType::Any(map->GetIsolate()), - FORCE_FIELD); + for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { + PropertyDetails details = descriptors->GetDetails(i); + if (details.type() == FIELD) { + map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD); } } return map; @@ -3958,9 +3790,7 @@ void JSObject::MigrateInstance(Handle object) { // transition that matches the object. This achieves what is needed. Handle original_map(object->map()); GeneralizeFieldRepresentation( - object, 0, Representation::None(), - HeapType::None(object->GetIsolate()), - ALLOW_AS_CONSTANT); + object, 0, Representation::None(), ALLOW_AS_CONSTANT); object->map()->set_migration_target(true); if (FLAG_trace_migration) { object->PrintInstanceMigration(stdout, *original_map, object->map()); @@ -3989,7 +3819,7 @@ MaybeHandle JSObject::SetPropertyUsingTransition( Handle transition_map(lookup->GetTransitionTarget()); int descriptor = transition_map->LastAdded(); - Handle descriptors(transition_map->instance_descriptors()); + DescriptorArray* descriptors = transition_map->instance_descriptors(); PropertyDetails details = descriptors->GetDetails(descriptor); if (details.type() == CALLBACKS || attributes != details.attributes()) { @@ -4006,19 +3836,17 @@ MaybeHandle JSObject::SetPropertyUsingTransition( // Keep the target CONSTANT if the same value is stored. // TODO(verwaest): Also support keeping the placeholder // (value->IsUninitialized) as constant. - if (!lookup->CanHoldValue(value)) { - Representation field_representation = value->OptimalRepresentation(); - Handle field_type = value->OptimalType( - lookup->isolate(), field_representation); - transition_map = Map::GeneralizeRepresentation( - transition_map, descriptor, - field_representation, field_type, FORCE_FIELD); + if (!lookup->CanHoldValue(value) || + (details.type() == CONSTANT && + descriptors->GetValue(descriptor) != *value)) { + transition_map = Map::GeneralizeRepresentation(transition_map, + descriptor, value->OptimalRepresentation(), FORCE_FIELD); } JSObject::MigrateToMap(object, transition_map); // Reload. - descriptors = handle(transition_map->instance_descriptors()); + descriptors = transition_map->instance_descriptors(); details = descriptors->GetDetails(descriptor); if (details.type() != FIELD) return value; @@ -4040,13 +3868,11 @@ MaybeHandle JSObject::SetPropertyUsingTransition( static void SetPropertyToField(LookupResult* lookup, Handle value) { Representation representation = lookup->representation(); - if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { - Representation field_representation = value->OptimalRepresentation(); - Handle field_type = value->OptimalType( - lookup->isolate(), field_representation); + if (!lookup->CanHoldValue(value) || + lookup->type() == CONSTANT) { JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), lookup->GetDescriptorIndex(), - field_representation, field_type, + value->OptimalRepresentation(), FORCE_FIELD); DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); int descriptor = lookup->GetDescriptorIndex(); @@ -4082,8 +3908,7 @@ static void ConvertAndSetLocalProperty(LookupResult* lookup, int descriptor_index = lookup->GetDescriptorIndex(); if (lookup->GetAttributes() == attributes) { JSObject::GeneralizeFieldRepresentation( - object, descriptor_index, Representation::Tagged(), - HeapType::Any(lookup->isolate()), FORCE_FIELD); + object, descriptor_index, Representation::Tagged(), FORCE_FIELD); } else { Handle old_map(object->map()); Handle new_map = Map::CopyGeneralizeAllRepresentations(old_map, @@ -7071,13 +6896,7 @@ Handle Map::CopyReplaceDescriptors(Handle map, map->set_transitions(*transitions); result->SetBackPointer(*map); } else { - int length = descriptors->number_of_descriptors(); - for (int i = 0; i < length; i++) { - descriptors->SetRepresentation(i, Representation::Tagged()); - if (descriptors->GetDetails(i).type() == FIELD) { - descriptors->SetValue(i, HeapType::Any()); - } - } + descriptors->InitializeRepresentations(Representation::Tagged()); } return result; @@ -8266,27 +8085,16 @@ Handle DescriptorArray::Merge(Handle left_map, (left_details.type() == CONSTANT && right_details.type() == CONSTANT && left->GetValue(descriptor) != right->GetValue(descriptor))) { - ASSERT(left_details.type() == CONSTANT || left_details.type() == FIELD); - ASSERT(right_details.type() == CONSTANT || right_details.type() == FIELD); Representation representation = left_details.representation().generalize( right_details.representation()); - Handle left_type = (left_details.type() == FIELD) - ? handle(left->GetFieldType(descriptor), isolate) - : left->GetValue(descriptor)->OptimalType(isolate, representation); - Handle right_type = (right_details.type() == FIELD) - ? handle(right->GetFieldType(descriptor), isolate) - : right->GetValue(descriptor)->OptimalType(isolate, representation); - Handle field_type = Map::GeneralizeFieldType( - left_type, right_type, isolate); - FieldDescriptor d(handle(left->GetKey(descriptor), isolate), + FieldDescriptor d(handle(left->GetKey(descriptor)), current_offset++, - field_type, right_details.attributes(), representation); result->Set(descriptor, &d); } else { - Descriptor d(handle(right->GetKey(descriptor), isolate), - handle(right->GetValue(descriptor), isolate), + Descriptor d(handle(right->GetKey(descriptor)), + handle(right->GetValue(descriptor), right->GetIsolate()), right_details); result->Set(descriptor, &d); } @@ -8295,27 +8103,16 @@ Handle DescriptorArray::Merge(Handle left_map, // |valid| -> |new_size| for (; descriptor < new_size; descriptor++) { PropertyDetails right_details = right->GetDetails(descriptor); - if (right_details.type() == FIELD) { - FieldDescriptor d(handle(right->GetKey(descriptor), isolate), + if (right_details.type() == FIELD || + (store_mode == FORCE_FIELD && descriptor == modify_index)) { + FieldDescriptor d(handle(right->GetKey(descriptor)), current_offset++, - handle(right->GetFieldType(descriptor), isolate), right_details.attributes(), right_details.representation()); result->Set(descriptor, &d); - } else if (store_mode == FORCE_FIELD && descriptor == modify_index) { - ASSERT_EQ(CONSTANT, right_details.type()); - Representation field_representation = right_details.representation(); - Handle field_type = right->GetValue(descriptor)->OptimalType( - isolate, field_representation); - FieldDescriptor d(handle(right->GetKey(descriptor), isolate), - current_offset++, - field_type, - right_details.attributes(), - field_representation); - result->Set(descriptor, &d); } else { - Descriptor d(handle(right->GetKey(descriptor), isolate), - handle(right->GetValue(descriptor), isolate), + Descriptor d(handle(right->GetKey(descriptor)), + handle(right->GetValue(descriptor), right->GetIsolate()), right_details); result->Set(descriptor, &d); } diff --git a/src/objects.h b/src/objects.h index e35d7f4..1f656bc 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1509,8 +1509,6 @@ class Object : public MaybeObject { return true; } - Handle OptimalType(Isolate* isolate, Representation representation); - inline MaybeObject* AllocateNewStorageFor(Heap* heap, Representation representation); @@ -2582,7 +2580,6 @@ class JSObject: public JSReceiver { static void GeneralizeFieldRepresentation(Handle object, int modify_index, Representation new_representation, - Handle new_field_type, StoreMode store_mode); // Convert the object to use the canonical dictionary @@ -3408,14 +3405,12 @@ class DescriptorArray: public FixedArray { inline Name* GetKey(int descriptor_number); inline Object** GetKeySlot(int descriptor_number); inline Object* GetValue(int descriptor_number); - inline void SetValue(int descriptor_number, Object* value); inline Object** GetValueSlot(int descriptor_number); inline Object** GetDescriptorStartSlot(int descriptor_number); inline Object** GetDescriptorEndSlot(int descriptor_number); inline PropertyDetails GetDetails(int descriptor_number); inline PropertyType GetType(int descriptor_number); inline int GetFieldIndex(int descriptor_number); - inline HeapType* GetFieldType(int descriptor_number); inline Object* GetConstant(int descriptor_number); inline Object* GetCallbacksObject(int descriptor_number); inline AccessorDescriptor* GetCallbacks(int descriptor_number); @@ -3423,6 +3418,7 @@ class DescriptorArray: public FixedArray { inline Name* GetSortedKey(int descriptor_number); inline int GetSortedKeyIndex(int descriptor_number); inline void SetSortedKey(int pointer, int descriptor_number); + inline void InitializeRepresentations(Representation representation); inline void SetRepresentation(int descriptor_number, Representation representation); @@ -5954,9 +5950,6 @@ class DependentCode: public FixedArray { // Group of code that depends on global property values in property cells // not being changed. kPropertyCellChangedGroup, - // Group of code that omit run-time type checks for the field(s) introduced - // by this map. - kFieldTypeGroup, // Group of code that depends on tenuring information in AllocationSites // not being changed. kAllocationSiteTenuringChangedGroup, @@ -6227,9 +6220,6 @@ class Map: public HeapObject { Map* FindRootMap(); Map* FindUpdatedMap(int verbatim, int length, DescriptorArray* descriptors); Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors); - Map* FindFieldOwner(int descriptor); - - void UpdateDescriptor(int descriptor_number, Descriptor* desc); inline int GetInObjectPropertyOffset(int index); @@ -6239,19 +6229,13 @@ class Map: public HeapObject { int target_number_of_fields, int target_inobject, int target_unused); - static Handle GeneralizeAllFieldRepresentations(Handle map); - static Handle GeneralizeFieldType(Handle old_field_type, - Handle new_field_type, - Isolate* isolate) - V8_WARN_UNUSED_RESULT; - static void GeneralizeFieldType(Handle map, - int modify_index, - Handle new_field_type); + static Handle GeneralizeAllFieldRepresentations( + Handle map, + Representation new_representation); static Handle GeneralizeRepresentation( Handle map, int modify_index, Representation new_representation, - Handle new_field_type, StoreMode store_mode); static Handle CopyGeneralizeAllRepresentations( Handle map, @@ -6267,9 +6251,7 @@ class Map: public HeapObject { int descriptors, bool constant_to_field, Representation old_representation, - Representation new_representation, - HeapType* old_field_type, - HeapType* new_field_type); + Representation new_representation); // Returns the constructor name (the name (possibly, inferred name) of the // function that was used to instantiate the object). diff --git a/src/property.cc b/src/property.cc index e7d0c4e..406caec 100644 --- a/src/property.cc +++ b/src/property.cc @@ -30,41 +30,60 @@ void LookupResult::Print(FILE* out) { PrintF(out, " -cacheable = %s\n", IsCacheable() ? "true" : "false"); PrintF(out, " -attributes = %x\n", GetAttributes()); if (IsTransition()) { - PrintF(out, " -transition target:\n"); - GetTransitionTarget()->Print(out); - PrintF(out, "\n"); - } - switch (type()) { - case NORMAL: - PrintF(out, " -type = normal\n"); - PrintF(out, " -entry = %d", GetDictionaryEntry()); - break; - case CONSTANT: - PrintF(out, " -type = constant\n"); - PrintF(out, " -value:\n"); - GetConstant()->Print(out); - PrintF(out, "\n"); - break; - case FIELD: - PrintF(out, " -type = field\n"); - PrintF(out, " -index = %d\n", GetFieldIndex().field_index()); - PrintF(out, " -field type:\n"); - GetFieldType()->TypePrint(out); - break; - case CALLBACKS: - PrintF(out, " -type = call backs\n"); - PrintF(out, " -callback object:\n"); - GetCallbackObject()->Print(out); - break; - case HANDLER: - PrintF(out, " -type = lookup proxy\n"); - break; - case INTERCEPTOR: - PrintF(out, " -type = lookup interceptor\n"); - break; - case NONEXISTENT: - UNREACHABLE(); - break; + switch (type()) { + case FIELD: + PrintF(out, " -type = map transition\n"); + PrintF(out, " -map:\n"); + GetTransitionTarget()->Print(out); + PrintF(out, "\n"); + break; + case CONSTANT: + PrintF(out, " -type = constant property transition\n"); + PrintF(out, " -map:\n"); + GetTransitionTarget()->Print(out); + PrintF(out, "\n"); + break; + case CALLBACKS: + PrintF(out, " -type = callbacks transition\n"); + PrintF(out, " -callback object:\n"); + GetCallbackObject()->Print(out); + break; + default: + UNREACHABLE(); + break; + } + } else { + switch (type()) { + case NORMAL: + PrintF(out, " -type = normal\n"); + PrintF(out, " -entry = %d", GetDictionaryEntry()); + break; + case CONSTANT: + PrintF(out, " -type = constant\n"); + PrintF(out, " -value:\n"); + GetConstant()->Print(out); + PrintF(out, "\n"); + break; + case FIELD: + PrintF(out, " -type = field\n"); + PrintF(out, " -index = %d", GetFieldIndex().field_index()); + PrintF(out, "\n"); + break; + case CALLBACKS: + PrintF(out, " -type = call backs\n"); + PrintF(out, " -callback object:\n"); + GetCallbackObject()->Print(out); + break; + case HANDLER: + PrintF(out, " -type = lookup proxy\n"); + break; + case INTERCEPTOR: + PrintF(out, " -type = lookup interceptor\n"); + break; + case NONEXISTENT: + UNREACHABLE(); + break; + } } } diff --git a/src/property.h b/src/property.h index 9e3b2a0..4ddcab0 100644 --- a/src/property.h +++ b/src/property.h @@ -7,7 +7,6 @@ #include "isolate.h" #include "factory.h" -#include "types.h" namespace v8 { namespace internal { @@ -75,15 +74,8 @@ class FieldDescriptor V8_FINAL : public Descriptor { int field_index, PropertyAttributes attributes, Representation representation) - : Descriptor(key, HeapType::Any(key->GetIsolate()), attributes, + : Descriptor(key, handle(Smi::FromInt(0), key->GetIsolate()), attributes, FIELD, representation, field_index) {} - FieldDescriptor(Handle key, - int field_index, - Handle field_type, - PropertyAttributes attributes, - Representation representation) - : Descriptor(key, field_type, attributes, FIELD, - representation, field_index) { } }; @@ -185,26 +177,9 @@ class LookupResult V8_FINAL BASE_EMBEDDED { number_ = number; } - bool CanHoldValue(Handle value) const { - switch (type()) { - case NORMAL: - return true; - case FIELD: - return value->FitsRepresentation(representation()) && - GetFieldType()->NowContains(value); - case CONSTANT: - ASSERT(GetConstant() != *value || - value->FitsRepresentation(representation())); - return GetConstant() == *value; - case CALLBACKS: - case HANDLER: - case INTERCEPTOR: - return true; - case NONEXISTENT: - UNREACHABLE(); - } - UNREACHABLE(); - return true; + bool CanHoldValue(Handle value) { + if (IsNormal()) return true; + return value->FitsRepresentation(details_.representation()); } void TransitionResult(JSObject* holder, Map* target) { @@ -483,32 +458,6 @@ class LookupResult V8_FINAL BASE_EMBEDDED { return map->instance_descriptors()->GetFieldIndex(number_); } - HeapType* GetFieldType() const { - ASSERT(type() == FIELD); - if (lookup_type_ == DESCRIPTOR_TYPE) { - return GetFieldTypeFromMap(holder()->map()); - } - ASSERT(lookup_type_ == TRANSITION_TYPE); - return GetFieldTypeFromMap(transition_); - } - - HeapType* GetFieldTypeFromMap(Map* map) const { - ASSERT(lookup_type_ == DESCRIPTOR_TYPE || - lookup_type_ == TRANSITION_TYPE); - ASSERT(number_ < map->NumberOfOwnDescriptors()); - return map->instance_descriptors()->GetFieldType(number_); - } - - Map* GetFieldOwner() const { - return GetFieldOwnerFromMap(holder()->map()); - } - - Map* GetFieldOwnerFromMap(Map* map) const { - ASSERT(lookup_type_ == DESCRIPTOR_TYPE); - ASSERT(number_ < map->NumberOfOwnDescriptors()); - return map->FindFieldOwner(number_); - } - void Iterate(ObjectVisitor* visitor); private: diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 44651cb..89f7cd0 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -4037,7 +4037,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { Condition cc = masm()->CheckSmi(value); DeoptimizeIf(cc, instr->environment()); - // We know now that value is not a smi, so we can omit the check below. + // We know that value is a smi now, so we can omit the check below. check_needed = OMIT_SMI_CHECK; } } diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 88e7f38..13e822d 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -494,13 +494,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, } else if (representation.IsSmi()) { __ JumpIfNotSmi(value_reg, miss_label); } else if (representation.IsHeapObject()) { - HeapType* field_type = descriptors->GetFieldType(descriptor); - if (field_type->IsClass()) { - __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK); - } else { - ASSERT(HeapType::Any()->Is(field_type)); - __ JumpIfSmi(value_reg, miss_label); - } + __ JumpIfSmi(value_reg, miss_label); } else if (representation.IsDouble()) { Label do_store, heap_number; __ AllocateHeapNumber(storage_reg, scratch1, slow); @@ -644,13 +638,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, if (representation.IsSmi()) { __ JumpIfNotSmi(value_reg, miss_label); } else if (representation.IsHeapObject()) { - HeapType* field_type = lookup->GetFieldType(); - if (field_type->IsClass()) { - __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK); - } else { - ASSERT(HeapType::Any()->Is(field_type)); - __ JumpIfSmi(value_reg, miss_label); - } + __ JumpIfSmi(value_reg, miss_label); } else if (representation.IsDouble()) { // Load the double storage. if (index < 0) { diff --git a/test/mjsunit/field-type-tracking.js b/test/mjsunit/field-type-tracking.js deleted file mode 100644 index 75c41da..0000000 --- a/test/mjsunit/field-type-tracking.js +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flags: --allow-natives-syntax --nostress-opt --track-field-types - -(function() { - var o = { text: "Hello World!" }; - function A() { - this.a = o; - } - function readA(x) { - return x.a; - } - var a = new A(); - assertUnoptimized(readA); - readA(a); readA(a); readA(a); - %OptimizeFunctionOnNextCall(readA); - assertEquals(readA(a), o); - assertOptimized(readA); - - var b = new A(); - b.b = o; - assertEquals(readA(b), o); - assertUnoptimized(readA); - %OptimizeFunctionOnNextCall(readA); - assertEquals(readA(a), o); - assertOptimized(readA); - assertEquals(readA(a), o); - assertEquals(readA(b), o); - assertOptimized(readA); - - function readAFromB(x) { - return x.a; - } - assertUnoptimized(readAFromB); - readAFromB(b); readAFromB(b); readAFromB(b); - %OptimizeFunctionOnNextCall(readAFromB); - assertEquals(readAFromB(b), o); - assertOptimized(readAFromB); - - var c = new A(); - c.c = o; - assertOptimized(readA); - assertOptimized(readAFromB); - c.a = [1]; - assertUnoptimized(readA); - assertUnoptimized(readAFromB); - assertEquals(readA(a), o); - assertEquals(readA(b), o); - assertEquals(readA(c), [1]); - assertEquals(readAFromB(b), o); - - %OptimizeFunctionOnNextCall(readA); - assertEquals(readA(a), o); - %OptimizeFunctionOnNextCall(readAFromB); - assertEquals(readAFromB(b), o); - assertOptimized(readA); - a.a = [1]; - assertEquals(readA(a), [1]); - assertEquals(readA(b), o); - assertEquals(readA(c), [1]); - assertOptimized(readA); - b.a = [1]; - assertEquals(readA(a), [1]); - assertEquals(readA(b), [1]); - assertEquals(readA(c), [1]); - assertOptimized(readA); - assertOptimized(readAFromB); -})(); - -(function() { - function A() { this.x = 0; } - A.prototype = {y: 20}; - function B(o) { return o.a.y; } - function C() { this.a = new A(); } - - B(new C()); - B(new C()); - %OptimizeFunctionOnNextCall(B); - var c = new C(); - assertEquals(20, B(c)); - assertOptimized(B); - c.a.y = 10; - assertEquals(10, B(c)); - assertUnoptimized(B); - - var c = new C(); - %OptimizeFunctionOnNextCall(B); - assertEquals(20, B(c)); - assertOptimized(B); - c.a.y = 30; - assertEquals(30, B(c)); - assertOptimized(B); -})(); - -(function() { - var x = new Object(); - x.a = 1 + "Long string that results in a cons string"; - x = JSON.parse('{"a":"Short"}'); -})(); - -(function() { - var x = {y: {z: 1}}; - x.y.z = 1.1; -})();