From 3a26dda780fb0de589e987924c71cb9182831df9 Mon Sep 17 00:00:00 2001 From: "olivf@chromium.org" Date: Mon, 10 Jun 2013 15:43:40 +0000 Subject: [PATCH] revert accidental dcommit git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15044 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/full-codegen-arm.cc | 5 ++++- src/code-stubs-hydrogen.cc | 2 +- src/code-stubs.cc | 31 ++++++++++++++++++++----------- src/code-stubs.h | 22 ++++++++++++++++------ src/hydrogen.cc | 26 +++++++++++++------------- src/hydrogen.h | 1 + src/ia32/full-codegen-ia32.cc | 5 ++++- src/ic.cc | 13 +++++++++++-- src/ic.h | 3 ++- src/mips/full-codegen-mips.cc | 5 ++++- src/stub-cache.cc | 2 ++ src/v8.h | 4 ++++ src/x64/full-codegen-x64.cc | 5 ++++- test/cctest/test-compare-nil-ic-stub.cc | 3 ++- 14 files changed, 88 insertions(+), 39 deletions(-) diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 08ae9b0..8f11769 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -4765,7 +4765,9 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, VisitForAccumulatorValue(sub_expr); PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - if (expr->op() == Token::EQ_STRICT) { + EqualityKind kind = expr->op() == Token::EQ_STRICT + ? kStrictEquality : kNonStrictEquality; + if (kind == kStrictEquality) { Heap::RootListIndex nil_value = nil == kNullValue ? Heap::kNullValueRootIndex : Heap::kUndefinedValueRootIndex; @@ -4774,6 +4776,7 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, Split(eq, if_true, if_false, fall_through); } else { Handle ic = CompareNilICStub::GetUninitialized(isolate(), + kNonStrictEquality, nil); CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); __ cmp(r0, Operand(0)); diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 99c4db5..4be21c3 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -736,7 +736,7 @@ HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { CompareNilICStub* stub = casted_stub(); HIfContinuation continuation; Handle sentinel_map(graph()->isolate()->heap()->meta_map()); - BuildCompareNil(GetParameter(0), + BuildCompareNil(GetParameter(0), stub->GetKind(), stub->GetTypes(), sentinel_map, RelocInfo::kNoPosition, &continuation); IfBuilder if_nil(this, &continuation); diff --git a/src/code-stubs.cc b/src/code-stubs.cc index 6b6e250..b4479da 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -432,18 +432,25 @@ void ICCompareStub::Generate(MacroAssembler* masm) { void CompareNilICStub::Record(Handle object) { ASSERT(types_ != Types::FullCompare()); - if (object->IsNull()) { - types_.Add(NULL_TYPE); - } else if (object->IsUndefined()) { - types_.Add(UNDEFINED); - } else if (object->IsUndetectableObject() || - object->IsOddball() || - !object->IsHeapObject()) { - types_ = Types::FullCompare(); - } else if (IsMonomorphic()) { - types_ = Types::FullCompare(); + if (equality_kind_ == kStrictEquality) { + // When testing for strict equality only one value will evaluate to true + types_.RemoveAll(); + types_.Add((nil_value_ == kNullValue) ? NULL_TYPE: + UNDEFINED); } else { - types_.Add(MONOMORPHIC_MAP); + if (object->IsNull()) { + types_.Add(NULL_TYPE); + } else if (object->IsUndefined()) { + types_.Add(UNDEFINED); + } else if (object->IsUndetectableObject() || + object->IsOddball() || + !object->IsHeapObject()) { + types_ = Types::FullCompare(); + } else if (IsMonomorphic()) { + types_ = Types::FullCompare(); + } else { + types_.Add(MONOMORPHIC_MAP); + } } } @@ -470,6 +477,8 @@ void CompareNilICStub::PrintName(StringStream* stream) { types_.Print(stream); stream->Add((nil_value_ == kNullValue) ? "(NullValue|": "(UndefinedValue|"); + stream->Add((equality_kind_ == kStrictEquality) ? "StrictEquality)": + "NonStrictEquality)"); } diff --git a/src/code-stubs.h b/src/code-stubs.h index 4a77ed4..f4e2b7d 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -1154,21 +1154,24 @@ class CompareNilICStub : public HydrogenCodeStub { // boolean flags we need to store. :-P STATIC_ASSERT(NUMBER_OF_TYPES <= 6); - CompareNilICStub(NilValue nil, Types types = Types()) + CompareNilICStub(EqualityKind kind, NilValue nil, Types types = Types()) : types_(types) { + equality_kind_ = kind; nil_value_ = nil; } CompareNilICStub(Code::ExtraICState ic_state, InitializationState init_state = INITIALIZED) : HydrogenCodeStub(init_state) { + equality_kind_ = EqualityKindField::decode(ic_state); nil_value_ = NilValueField::decode(ic_state); types_ = Types(ExtractTypesFromExtraICState(ic_state)); } static Handle GetUninitialized(Isolate* isolate, + EqualityKind kind, NilValue nil) { - return CompareNilICStub(nil, UNINITIALIZED).GetCode(isolate); + return CompareNilICStub(kind, nil, UNINITIALIZED).GetCode(isolate); } virtual void InitializeInterfaceDescriptor( @@ -1176,7 +1179,7 @@ class CompareNilICStub : public HydrogenCodeStub { CodeStubInterfaceDescriptor* descriptor); static void InitializeForIsolate(Isolate* isolate) { - CompareNilICStub compare_stub(kNullValue, UNINITIALIZED); + CompareNilICStub compare_stub(kStrictEquality, kNullValue, UNINITIALIZED); compare_stub.InitializeInterfaceDescriptor( isolate, isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); @@ -1196,9 +1199,10 @@ class CompareNilICStub : public HydrogenCodeStub { Handle GenerateCode(); - // extra ic state = nil_value | type_n-1 | ... | type_0 + // extra ic state = nil_value | equality_kind | type_n-1 | ... | type_0 virtual Code::ExtraICState GetExtraICState() { return NilValueField::encode(nil_value_) | + EqualityKindField::encode(equality_kind_) | types_.ToIntegral(); } static byte ExtractTypesFromExtraICState( @@ -1209,26 +1213,32 @@ class CompareNilICStub : public HydrogenCodeStub { void Record(Handle object); bool IsMonomorphic() const { return types_.Contains(MONOMORPHIC_MAP); } + EqualityKind GetKind() const { return equality_kind_; } NilValue GetNilValue() const { return nil_value_; } Types GetTypes() const { return types_; } void ClearTypes() { types_.RemoveAll(); } + void SetKind(EqualityKind kind) { equality_kind_ = kind; } virtual void PrintName(StringStream* stream); private: friend class CompareNilIC; - CompareNilICStub(NilValue nil, + CompareNilICStub(EqualityKind kind, NilValue nil, InitializationState init_state) : HydrogenCodeStub(init_state) { + equality_kind_ = kind; nil_value_ = nil; } - class NilValueField : public BitField {}; + class EqualityKindField : public BitField { + }; + class NilValueField : public BitField {}; virtual CodeStub::Major MajorKey() { return CompareNilIC; } virtual int NotMissMinorKey() { return GetExtraICState(); } + EqualityKind equality_kind_; NilValue nil_value_; Types types_; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 6195eef..60edbb7 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -1698,6 +1698,7 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context, void HGraphBuilder::BuildCompareNil( HValue* value, + EqualityKind kind, CompareNilICStub::Types types, Handle map, int position, @@ -1732,7 +1733,9 @@ void HGraphBuilder::BuildCompareNil( // emitted below is the actual monomorphic map. BuildCheckMap(value, map); } else { - if_nil.Deopt(); + if (kind == kNonStrictEquality) { + if_nil.Deopt(); + } } } @@ -9918,22 +9921,19 @@ void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, ASSERT(!HasStackOverflow()); ASSERT(current_block() != NULL); ASSERT(current_block()->HasPredecessor()); + EqualityKind kind = + expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality; HIfContinuation continuation; CompareNilICStub::Types types; - if (expr->op() == Token::EQ_STRICT) { - IfBuilder if_nil(this); - if_nil.If( - value, (nil== kNullValue) ? graph()->GetConstantNull() - : graph()->GetConstantUndefined()); - if_nil.Then(); - if_nil.Else(); - if_nil.CaptureContinuation(&continuation); - return ast_context()->ReturnContinuation(&continuation, expr->id()); + if (kind == kStrictEquality) { + types.Add((nil == kNullValue) ? CompareNilICStub::NULL_TYPE : + CompareNilICStub::UNDEFINED); + } else { + types = CompareNilICStub::Types(expr->compare_nil_types()); + if (types.IsEmpty()) types = CompareNilICStub::Types::FullCompare(); } - types = CompareNilICStub::Types(expr->compare_nil_types()); - if (types.IsEmpty()) types = CompareNilICStub::Types::FullCompare(); Handle map_handle = expr->map(); - BuildCompareNil(value, types, map_handle, + BuildCompareNil(value, kind, types, map_handle, expr->position(), &continuation); return ast_context()->ReturnContinuation(&continuation, expr->id()); } diff --git a/src/hydrogen.h b/src/hydrogen.h index 160ffef..eb6473a 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -1353,6 +1353,7 @@ class HGraphBuilder { void BuildCompareNil( HValue* value, + EqualityKind kind, CompareNilICStub::Types types, Handle map, int position, diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index afca4ce..7aff6e1 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -4768,14 +4768,17 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, VisitForAccumulatorValue(sub_expr); PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); + EqualityKind kind = expr->op() == Token::EQ_STRICT + ? kStrictEquality : kNonStrictEquality; Handle nil_value = nil == kNullValue ? isolate()->factory()->null_value() : isolate()->factory()->undefined_value(); - if (expr->op() == Token::EQ_STRICT) { + if (kind == kStrictEquality) { __ cmp(eax, nil_value); Split(equal, if_true, if_false, fall_through); } else { Handle ic = CompareNilICStub::GetUninitialized(isolate(), + kNonStrictEquality, nil); CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); __ test(eax, eax); diff --git a/src/ic.cc b/src/ic.cc index 94e8773..db1cb95 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -2943,8 +2943,16 @@ void CompareNilIC::Clear(Address address, Code* target) { } -MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil, +MaybeObject* CompareNilIC::DoCompareNilSlow(EqualityKind kind, + NilValue nil, Handle object) { + if (kind == kStrictEquality) { + if (nil == kNullValue) { + return Smi::FromInt(object->IsNull()); + } else { + return Smi::FromInt(object->IsUndefined()); + } + } if (object->IsNull() || object->IsUndefined()) { return Smi::FromInt(true); } @@ -2965,6 +2973,7 @@ MaybeObject* CompareNilIC::CompareNil(Handle object) { stub.Record(object); old_types.TraceTransition(stub.GetTypes()); + EqualityKind kind = stub.GetKind(); NilValue nil = stub.GetNilValue(); // Find or create the specialized stub to support the new set of types. @@ -2978,7 +2987,7 @@ MaybeObject* CompareNilIC::CompareNil(Handle object) { code = stub.GetCode(isolate()); } set_target(*code); - return DoCompareNilSlow(nil, object); + return DoCompareNilSlow(kind, nil, object); } diff --git a/src/ic.h b/src/ic.h index 8c448eb..dadb743 100644 --- a/src/ic.h +++ b/src/ic.h @@ -789,7 +789,8 @@ class CompareNilIC: public IC { static void Clear(Address address, Code* target); - static MUST_USE_RESULT MaybeObject* DoCompareNilSlow(NilValue nil, + static MUST_USE_RESULT MaybeObject* DoCompareNilSlow(EqualityKind kind, + NilValue nil, Handle object); }; diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 8414001..10afeb1 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -4805,8 +4805,10 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, VisitForAccumulatorValue(sub_expr); PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); + EqualityKind kind = expr->op() == Token::EQ_STRICT + ? kStrictEquality : kNonStrictEquality; __ mov(a0, result_register()); - if (expr->op() == Token::EQ_STRICT) { + if (kind == kStrictEquality) { Heap::RootListIndex nil_value = nil == kNullValue ? Heap::kNullValueRootIndex : Heap::kUndefinedValueRootIndex; @@ -4814,6 +4816,7 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, Split(eq, a0, Operand(a1), if_true, if_false, fall_through); } else { Handle ic = CompareNilICStub::GetUninitialized(isolate(), + kNonStrictEquality, nil); CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through); diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 0f81669..69513da 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -909,6 +909,8 @@ Handle StubCache::ComputeCallMiss(int argc, Handle StubCache::ComputeCompareNil(Handle receiver_map, CompareNilICStub& stub) { + stub.SetKind(kNonStrictEquality); + Handle name(isolate_->heap()->empty_string()); if (!receiver_map->is_shared()) { Handle cached_ic = FindIC(name, receiver_map, Code::COMPARE_NIL_IC, diff --git a/src/v8.h b/src/v8.h index e906035..cd25dc7 100644 --- a/src/v8.h +++ b/src/v8.h @@ -146,6 +146,10 @@ class V8 : public AllStatic { enum NilValue { kNullValue, kUndefinedValue }; +// JavaScript defines two kinds of equality. +enum EqualityKind { kStrictEquality, kNonStrictEquality }; + + } } // namespace v8::internal namespace i = v8::internal; diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index be2b54d..53d7027 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -4754,7 +4754,9 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, VisitForAccumulatorValue(sub_expr); PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); - if (expr->op() == Token::EQ_STRICT) { + EqualityKind kind = expr->op() == Token::EQ_STRICT + ? kStrictEquality : kNonStrictEquality; + if (kind == kStrictEquality) { Heap::RootListIndex nil_value = nil == kNullValue ? Heap::kNullValueRootIndex : Heap::kUndefinedValueRootIndex; @@ -4762,6 +4764,7 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, Split(equal, if_true, if_false, fall_through); } else { Handle ic = CompareNilICStub::GetUninitialized(isolate(), + kNonStrictEquality, nil); CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); __ testq(rax, rax); diff --git a/test/cctest/test-compare-nil-ic-stub.cc b/test/cctest/test-compare-nil-ic-stub.cc index affb8bd..6177fde 100644 --- a/test/cctest/test-compare-nil-ic-stub.cc +++ b/test/cctest/test-compare-nil-ic-stub.cc @@ -46,8 +46,9 @@ TEST(TypeConstructors) { TEST(ExternalICStateParsing) { Types types; types.Add(CompareNilICStub::UNDEFINED); - CompareNilICStub stub(kUndefinedValue, types); + CompareNilICStub stub(kNonStrictEquality, kUndefinedValue, types); CompareNilICStub stub2(stub.GetExtraICState()); + CHECK_EQ(stub.GetKind(), stub2.GetKind()); CHECK_EQ(stub.GetNilValue(), stub2.GetNilValue()); CHECK_EQ(stub.GetTypes().ToIntegral(), stub2.GetTypes().ToIntegral()); } -- 2.7.4