From 6c21d125d4d4c8ce2d11e751c04203259d03dd24 Mon Sep 17 00:00:00 2001 From: "palfia@homejinni.com" Date: Thu, 30 May 2013 01:24:45 +0000 Subject: [PATCH] MIPS: Convert ToBooleanStub to a HydrogenStub. Currently just using the existing HBranch instruction, which is still fully implemented in Lithium. Will refactor HBranch in a next CL. Port r14886 (068e9135) BUG= Review URL: https://codereview.chromium.org/15664008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14893 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/code-stubs-mips.cc | 123 +++++------------------------------------- src/mips/full-codegen-mips.cc | 10 ++-- 2 files changed, 19 insertions(+), 114 deletions(-) diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 9b4170e..1890d7b 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -176,6 +176,19 @@ void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( } +void ToBooleanStub::InitializeInterfaceDescriptor( + Isolate* isolate, + CodeStubInterfaceDescriptor* descriptor) { + static Register registers[] = { a0 }; + descriptor->register_param_count_ = 1; + descriptor->register_params_ = registers; + descriptor->deoptimization_handler_ = + FUNCTION_ADDR(ToBooleanIC_Miss); + descriptor->SetMissHandler( + ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate)); +} + + #define __ ACCESS_MASM(masm) static void EmitIdenticalObjectComparison(MacroAssembler* masm, @@ -1500,116 +1513,6 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { } -// The stub expects its argument in the tos_ register and returns its result in -// it, too: zero for false, and a non-zero value for true. -void ToBooleanStub::Generate(MacroAssembler* masm) { - Label patch; - const Register map = t5.is(tos_) ? t3 : t5; - - // undefined -> false. - CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false); - - // Boolean -> its value. - CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false); - CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true); - - // 'null' -> false. - CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false); - - if (types_.Contains(SMI)) { - // Smis: 0 -> false, all other -> true - __ And(at, tos_, kSmiTagMask); - // tos_ contains the correct return value already - __ Ret(eq, at, Operand(zero_reg)); - } else if (types_.NeedsMap()) { - // If we need a map later and have a Smi -> patch. - __ JumpIfSmi(tos_, &patch); - } - - if (types_.NeedsMap()) { - __ lw(map, FieldMemOperand(tos_, HeapObject::kMapOffset)); - - if (types_.CanBeUndetectable()) { - __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset)); - __ And(at, at, Operand(1 << Map::kIsUndetectable)); - // Undetectable -> false. - __ Movn(tos_, zero_reg, at); - __ Ret(ne, at, Operand(zero_reg)); - } - } - - if (types_.Contains(SPEC_OBJECT)) { - // Spec object -> true. - __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); - // tos_ contains the correct non-zero return value already. - __ Ret(ge, at, Operand(FIRST_SPEC_OBJECT_TYPE)); - } - - if (types_.Contains(STRING)) { - // String value -> false iff empty. - __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); - Label skip; - __ Branch(&skip, ge, at, Operand(FIRST_NONSTRING_TYPE)); - __ Ret(USE_DELAY_SLOT); // the string length is OK as the return value - __ lw(tos_, FieldMemOperand(tos_, String::kLengthOffset)); - __ bind(&skip); - } - - if (types_.Contains(HEAP_NUMBER)) { - // Heap number -> false iff +0, -0, or NaN. - Label not_heap_number; - __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); - __ Branch(¬_heap_number, ne, map, Operand(at)); - Label zero_or_nan, number; - __ ldc1(f2, FieldMemOperand(tos_, HeapNumber::kValueOffset)); - __ BranchF(&number, &zero_or_nan, ne, f2, kDoubleRegZero); - // "tos_" is a register, and contains a non zero value by default. - // Hence we only need to overwrite "tos_" with zero to return false for - // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true. - __ bind(&zero_or_nan); - __ mov(tos_, zero_reg); - __ bind(&number); - __ Ret(); - __ bind(¬_heap_number); - } - - __ bind(&patch); - GenerateTypeTransition(masm); -} - - -void ToBooleanStub::CheckOddball(MacroAssembler* masm, - Type type, - Heap::RootListIndex value, - bool result) { - if (types_.Contains(type)) { - // If we see an expected oddball, return its ToBoolean value tos_. - __ LoadRoot(at, value); - __ Subu(at, at, tos_); // This is a check for equality for the movz below. - // The value of a root is never NULL, so we can avoid loading a non-null - // value into tos_ when we want to return 'true'. - if (!result) { - __ Movz(tos_, zero_reg, at); - } - __ Ret(eq, at, Operand(zero_reg)); - } -} - - -void ToBooleanStub::GenerateTypeTransition(MacroAssembler* masm) { - __ Move(a3, tos_); - __ li(a2, Operand(Smi::FromInt(tos_.code()))); - __ li(a1, Operand(Smi::FromInt(types_.ToByte()))); - __ Push(a3, a2, a1); - // Patch the caller to an appropriate specialized stub and return the - // operation result to the caller of the stub. - __ TailCallExternalReference( - ExternalReference(IC_Utility(IC::kToBoolean_Patch), masm->isolate()), - 3, - 1); -} - - void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { // We don't allow a GC during a store buffer overflow so there is no need to // store the registers in any particular way, but we do have to store and diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 6a3b72d..78f44ab 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -677,8 +677,9 @@ void FullCodeGenerator::DoTest(Expression* condition, Label* if_true, Label* if_false, Label* fall_through) { - ToBooleanStub stub(result_register()); - __ CallStub(&stub, condition->test_id()); + __ mov(a0, result_register()); + Handle ic = ToBooleanStub::GetUninitialized(isolate()); + CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); __ mov(at, zero_reg); Split(ne, v0, Operand(at), if_true, if_false, fall_through); } @@ -2061,8 +2062,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) { Handle done_ic = isolate()->builtins()->LoadIC_Initialize(); CallIC(done_ic); // result.done in v0 __ Addu(sp, sp, Operand(kPointerSize)); // drop LoadIC state - ToBooleanStub stub(v0); - __ CallStub(&stub); + __ mov(a0, v0); + Handle bool_ic = ToBooleanStub::GetUninitialized(isolate()); + CallIC(bool_ic); __ Branch(&l_try, eq, v0, Operand(zero_reg)); // result.value -- 2.7.4