revert accidental dcommit
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15044 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
23691cf023
commit
3a26dda780
@ -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<Code> ic = CompareNilICStub::GetUninitialized(isolate(),
|
||||
kNonStrictEquality,
|
||||
nil);
|
||||
CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId());
|
||||
__ cmp(r0, Operand(0));
|
||||
|
@ -736,7 +736,7 @@ HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() {
|
||||
CompareNilICStub* stub = casted_stub();
|
||||
HIfContinuation continuation;
|
||||
Handle<Map> 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);
|
||||
|
@ -432,18 +432,25 @@ void ICCompareStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
void CompareNilICStub::Record(Handle<Object> 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)");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<Code> 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<Code> 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> 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<NilValue, NUMBER_OF_TYPES, 1> {};
|
||||
class EqualityKindField : public BitField<EqualityKind, NUMBER_OF_TYPES, 1> {
|
||||
};
|
||||
class NilValueField : public BitField<NilValue, NUMBER_OF_TYPES+1, 1> {};
|
||||
|
||||
virtual CodeStub::Major MajorKey() { return CompareNilIC; }
|
||||
virtual int NotMissMinorKey() { return GetExtraICState(); }
|
||||
|
||||
EqualityKind equality_kind_;
|
||||
NilValue nil_value_;
|
||||
Types types_;
|
||||
|
||||
|
@ -1698,6 +1698,7 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context,
|
||||
|
||||
void HGraphBuilder::BuildCompareNil(
|
||||
HValue* value,
|
||||
EqualityKind kind,
|
||||
CompareNilICStub::Types types,
|
||||
Handle<Map> 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<HCompareObjectEqAndBranch>(
|
||||
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> 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());
|
||||
}
|
||||
|
@ -1353,6 +1353,7 @@ class HGraphBuilder {
|
||||
|
||||
void BuildCompareNil(
|
||||
HValue* value,
|
||||
EqualityKind kind,
|
||||
CompareNilICStub::Types types,
|
||||
Handle<Map> map,
|
||||
int position,
|
||||
|
@ -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<Object> 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<Code> ic = CompareNilICStub::GetUninitialized(isolate(),
|
||||
kNonStrictEquality,
|
||||
nil);
|
||||
CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId());
|
||||
__ test(eax, eax);
|
||||
|
13
src/ic.cc
13
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> 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> 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> object) {
|
||||
code = stub.GetCode(isolate());
|
||||
}
|
||||
set_target(*code);
|
||||
return DoCompareNilSlow(nil, object);
|
||||
return DoCompareNilSlow(kind, nil, object);
|
||||
}
|
||||
|
||||
|
||||
|
3
src/ic.h
3
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> object);
|
||||
};
|
||||
|
||||
|
@ -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<Code> 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);
|
||||
|
@ -909,6 +909,8 @@ Handle<Code> StubCache::ComputeCallMiss(int argc,
|
||||
|
||||
Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map,
|
||||
CompareNilICStub& stub) {
|
||||
stub.SetKind(kNonStrictEquality);
|
||||
|
||||
Handle<String> name(isolate_->heap()->empty_string());
|
||||
if (!receiver_map->is_shared()) {
|
||||
Handle<Code> cached_ic = FindIC(name, receiver_map, Code::COMPARE_NIL_IC,
|
||||
|
4
src/v8.h
4
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;
|
||||
|
@ -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<Code> ic = CompareNilICStub::GetUninitialized(isolate(),
|
||||
kNonStrictEquality,
|
||||
nil);
|
||||
CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId());
|
||||
__ testq(rax, rax);
|
||||
|
@ -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());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user