From d1df58e8d734ceb7d475b9c83263466f6ccd9031 Mon Sep 17 00:00:00 2001 From: bmeurer Date: Mon, 29 Feb 2016 04:16:00 -0800 Subject: [PATCH] [stubs] Introduce a proper ToBooleanStub. Rename the existing (patching) ToBooleanStub to ToBooleanICStub to match our naming convention, and add a new TurboFan-powered ToBooleanStub, which just does the ToBoolean conversion without any runtime call or code patching, so we can use it for Ignition (and TurboFan). Drive-by-fix: Add an Oddball::to_boolean field similar to the ones we already have for to_string and to_number, so we don't need to actually dispatch on the concrete Oddball at all. R=epertoso@chromium.org, rmcilroy@chromium.org, yangguo@chromium.org Review URL: https://codereview.chromium.org/1744163002 Cr-Commit-Position: refs/heads/master@{#34361} --- include/v8.h | 2 +- src/code-factory.cc | 4 +- src/code-stubs-hydrogen.cc | 11 +- src/code-stubs.cc | 183 +++++++++++++++--- src/code-stubs.h | 32 +-- src/compiler/code-stub-assembler.cc | 6 + src/compiler/code-stub-assembler.h | 7 +- src/compiler/js-generic-lowering.cc | 3 +- src/compiler/linkage.cc | 3 +- .../mips/instruction-selector-mips.cc | 36 ++-- .../mips64/instruction-selector-mips64.cc | 36 ++-- src/compiler/type-hint-analyzer.cc | 8 +- src/crankshaft/arm/lithium-arm.cc | 6 +- src/crankshaft/arm/lithium-codegen-arm.cc | 23 +-- src/crankshaft/arm64/lithium-arm64.cc | 2 +- src/crankshaft/arm64/lithium-codegen-arm64.cc | 23 +-- src/crankshaft/hydrogen-instructions.cc | 18 +- src/crankshaft/hydrogen-instructions.h | 17 +- src/crankshaft/hydrogen-osr.cc | 2 +- src/crankshaft/hydrogen.cc | 8 +- src/crankshaft/ia32/lithium-codegen-ia32.cc | 23 +-- src/crankshaft/ia32/lithium-ia32.cc | 6 +- src/crankshaft/mips/lithium-codegen-mips.cc | 23 +-- src/crankshaft/mips/lithium-mips.cc | 6 +- .../mips64/lithium-codegen-mips64.cc | 23 +-- src/crankshaft/mips64/lithium-mips64.cc | 6 +- src/crankshaft/ppc/lithium-codegen-ppc.cc | 23 +-- src/crankshaft/ppc/lithium-ppc.cc | 6 +- src/crankshaft/x64/lithium-codegen-x64.cc | 23 +-- src/crankshaft/x64/lithium-x64.cc | 6 +- src/crankshaft/x87/lithium-codegen-x87.cc | 23 +-- src/crankshaft/x87/lithium-x87.cc | 6 +- src/factory.cc | 6 +- src/factory.h | 4 +- src/full-codegen/arm/full-codegen-arm.cc | 2 +- src/full-codegen/arm64/full-codegen-arm64.cc | 2 +- src/full-codegen/ia32/full-codegen-ia32.cc | 2 +- src/full-codegen/mips/full-codegen-mips.cc | 2 +- .../mips64/full-codegen-mips64.cc | 2 +- src/full-codegen/ppc/full-codegen-ppc.cc | 2 +- src/full-codegen/x64/full-codegen-x64.cc | 2 +- src/full-codegen/x87/full-codegen-x87.cc | 2 +- src/heap/heap-inl.h | 3 +- src/heap/heap.cc | 56 ++++-- src/heap/heap.h | 2 +- src/ic/ic.cc | 2 +- src/interpreter/interpreter.cc | 40 +++- src/objects-inl.h | 1 + src/objects.cc | 4 +- src/objects.h | 8 +- src/runtime/runtime-interpreter.cc | 16 -- src/runtime/runtime.h | 2 - src/type-info.h | 2 +- .../runtime/runtime-interpreter-unittest.cc | 73 ------- test/unittests/unittests.gyp | 1 - 55 files changed, 476 insertions(+), 364 deletions(-) delete mode 100644 test/unittests/runtime/runtime-interpreter-unittest.cc diff --git a/include/v8.h b/include/v8.h index db4c31e904..f804496eaf 100644 --- a/include/v8.h +++ b/include/v8.h @@ -7164,7 +7164,7 @@ class Internals { 1 * kApiPointerSize + kApiIntSize; static const int kStringResourceOffset = 3 * kApiPointerSize; - static const int kOddballKindOffset = 4 * kApiPointerSize; + static const int kOddballKindOffset = 5 * kApiPointerSize; static const int kForeignAddressOffset = kApiPointerSize; static const int kJSObjectHeaderSize = 3 * kApiPointerSize; static const int kFixedArrayHeaderSize = 2 * kApiPointerSize; diff --git a/src/code-factory.cc b/src/code-factory.cc index acec002c40..e4dd9bc676 100644 --- a/src/code-factory.cc +++ b/src/code-factory.cc @@ -134,8 +134,8 @@ Callable CodeFactory::InstanceOf(Isolate* isolate) { // static Callable CodeFactory::ToBoolean(Isolate* isolate) { - Handle code = ToBooleanStub::GetUninitialized(isolate); - return Callable(code, ToBooleanDescriptor(isolate)); + ToBooleanStub stub(isolate); + return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); } diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 07177a277a..b3446b6cb7 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -1681,10 +1681,9 @@ Handle StringAddStub::GenerateCode() { return DoGenerateCode(this); } - template <> -HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { - ToBooleanStub* stub = casted_stub(); +HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { + ToBooleanICStub* stub = casted_stub(); IfBuilder if_true(this); if_true.If(GetParameter(0), stub->types()); if_true.Then(); @@ -1694,11 +1693,7 @@ HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { return graph()->GetConstantFalse(); } - -Handle ToBooleanStub::GenerateCode() { - return DoGenerateCode(this); -} - +Handle ToBooleanICStub::GenerateCode() { return DoGenerateCode(this); } template <> HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { diff --git a/src/code-stubs.cc b/src/code-stubs.cc index 346ef75172..2c4445f59d 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -473,6 +473,144 @@ void StringLengthStub::GenerateAssembly( assembler->Return(result); } +void ToBooleanStub::GenerateAssembly( + compiler::CodeStubAssembler* assembler) const { + typedef compiler::Node Node; + typedef compiler::CodeStubAssembler::Label Label; + + Node* value = assembler->Parameter(0); + Label if_valueissmi(assembler), if_valueisnotsmi(assembler); + + // Check if {value} is a Smi or a HeapObject. + assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi, + &if_valueisnotsmi); + + assembler->Bind(&if_valueissmi); + { + // The {value} is a Smi, only need to check against zero. + Label if_valueiszero(assembler), if_valueisnotzero(assembler); + assembler->Branch(assembler->SmiEqual(value, assembler->SmiConstant(0)), + &if_valueiszero, &if_valueisnotzero); + + assembler->Bind(&if_valueiszero); + assembler->Return(assembler->BooleanConstant(false)); + + assembler->Bind(&if_valueisnotzero); + assembler->Return(assembler->BooleanConstant(true)); + } + + assembler->Bind(&if_valueisnotsmi); + { + Label if_valueisstring(assembler), if_valueisheapnumber(assembler), + if_valueisoddball(assembler), if_valueisother(assembler); + + // The {value} is a HeapObject, load its map. + Node* value_map = assembler->LoadObjectField(value, HeapObject::kMapOffset); + + // Load the {value}s instance type. + Node* value_instancetype = assembler->Load( + MachineType::Uint8(), value_map, + assembler->IntPtrConstant(Map::kInstanceTypeOffset - kHeapObjectTag)); + + // Dispatch based on the instance type; we distinguish all String instance + // types, the HeapNumber type and the Oddball type. + size_t const kNumCases = FIRST_NONSTRING_TYPE + 2; + Label* case_labels[kNumCases]; + int32_t case_values[kNumCases]; + for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) { + case_labels[i] = new Label(assembler); + case_values[i] = i; + } + case_labels[FIRST_NONSTRING_TYPE + 0] = &if_valueisheapnumber; + case_values[FIRST_NONSTRING_TYPE + 0] = HEAP_NUMBER_TYPE; + case_labels[FIRST_NONSTRING_TYPE + 1] = &if_valueisoddball; + case_values[FIRST_NONSTRING_TYPE + 1] = ODDBALL_TYPE; + assembler->Switch(value_instancetype, &if_valueisother, case_values, + case_labels, arraysize(case_values)); + for (int32_t i = 0; i < FIRST_NONSTRING_TYPE; ++i) { + assembler->Bind(case_labels[i]); + assembler->Goto(&if_valueisstring); + delete case_labels[i]; + } + + assembler->Bind(&if_valueisstring); + { + // Load the string length field of the {value}. + Node* value_length = + assembler->LoadObjectField(value, String::kLengthOffset); + + // Check if the {value} is the empty string. + Label if_valueisempty(assembler), if_valueisnotempty(assembler); + assembler->Branch( + assembler->SmiEqual(value_length, assembler->SmiConstant(0)), + &if_valueisempty, &if_valueisnotempty); + + assembler->Bind(&if_valueisempty); + assembler->Return(assembler->BooleanConstant(false)); + + assembler->Bind(&if_valueisnotempty); + assembler->Return(assembler->BooleanConstant(true)); + } + + assembler->Bind(&if_valueisheapnumber); + { + Node* value_value = assembler->Load( + MachineType::Float64(), value, + assembler->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag)); + + Label if_valueispositive(assembler), if_valueisnotpositive(assembler), + if_valueisnegative(assembler), if_valueisnanorzero(assembler); + assembler->Branch(assembler->Float64LessThan( + assembler->Float64Constant(0.0), value_value), + &if_valueispositive, &if_valueisnotpositive); + + assembler->Bind(&if_valueispositive); + assembler->Return(assembler->BooleanConstant(true)); + + assembler->Bind(&if_valueisnotpositive); + assembler->Branch(assembler->Float64LessThan( + value_value, assembler->Float64Constant(0.0)), + &if_valueisnegative, &if_valueisnanorzero); + + assembler->Bind(&if_valueisnegative); + assembler->Return(assembler->BooleanConstant(true)); + + assembler->Bind(&if_valueisnanorzero); + assembler->Return(assembler->BooleanConstant(false)); + } + + assembler->Bind(&if_valueisoddball); + { + // The {value} is an Oddball, and every Oddball knows its boolean value. + Node* value_toboolean = + assembler->LoadObjectField(value, Oddball::kToBooleanOffset); + assembler->Return(value_toboolean); + } + + assembler->Bind(&if_valueisother); + { + Node* value_map_bitfield = assembler->Load( + MachineType::Uint8(), value_map, + assembler->IntPtrConstant(Map::kBitFieldOffset - kHeapObjectTag)); + Node* value_map_undetectable = assembler->Word32And( + value_map_bitfield, + assembler->Int32Constant(1 << Map::kIsUndetectable)); + + // Check if the {value} is undetectable. + Label if_valueisundetectable(assembler), + if_valueisnotundetectable(assembler); + assembler->Branch(assembler->Word32Equal(value_map_undetectable, + assembler->Int32Constant(0)), + &if_valueisnotundetectable, &if_valueisundetectable); + + assembler->Bind(&if_valueisundetectable); + assembler->Return(assembler->BooleanConstant(false)); + + assembler->Bind(&if_valueisnotundetectable); + assembler->Return(assembler->BooleanConstant(true)); + } + } +} template void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { @@ -667,8 +805,7 @@ void AllocateInNewSpaceStub::InitializeDescriptor( descriptor->Initialize(); } - -void ToBooleanStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { +void ToBooleanICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { descriptor->Initialize(FUNCTION_ADDR(Runtime_ToBooleanIC_Miss)); descriptor->SetMissHandler(ExternalReference( Runtime::FunctionForId(Runtime::kToBooleanIC_Miss), isolate())); @@ -770,8 +907,7 @@ std::ostream& ArrayConstructorStubBase::BasePrintName( return os; } - -bool ToBooleanStub::UpdateStatus(Handle object) { +bool ToBooleanICStub::UpdateStatus(Handle object) { Types new_types = types(); Types old_types = new_types; bool to_boolean_value = new_types.UpdateStatus(object); @@ -780,30 +916,27 @@ bool ToBooleanStub::UpdateStatus(Handle object) { return to_boolean_value; } - -void ToBooleanStub::PrintState(std::ostream& os) const { // NOLINT +void ToBooleanICStub::PrintState(std::ostream& os) const { // NOLINT os << types(); } - -std::ostream& operator<<(std::ostream& os, const ToBooleanStub::Types& s) { +std::ostream& operator<<(std::ostream& os, const ToBooleanICStub::Types& s) { os << "("; SimpleListPrinter p(os); if (s.IsEmpty()) p.Add("None"); - if (s.Contains(ToBooleanStub::UNDEFINED)) p.Add("Undefined"); - if (s.Contains(ToBooleanStub::BOOLEAN)) p.Add("Bool"); - if (s.Contains(ToBooleanStub::NULL_TYPE)) p.Add("Null"); - if (s.Contains(ToBooleanStub::SMI)) p.Add("Smi"); - if (s.Contains(ToBooleanStub::SPEC_OBJECT)) p.Add("SpecObject"); - if (s.Contains(ToBooleanStub::STRING)) p.Add("String"); - if (s.Contains(ToBooleanStub::SYMBOL)) p.Add("Symbol"); - if (s.Contains(ToBooleanStub::HEAP_NUMBER)) p.Add("HeapNumber"); - if (s.Contains(ToBooleanStub::SIMD_VALUE)) p.Add("SimdValue"); + if (s.Contains(ToBooleanICStub::UNDEFINED)) p.Add("Undefined"); + if (s.Contains(ToBooleanICStub::BOOLEAN)) p.Add("Bool"); + if (s.Contains(ToBooleanICStub::NULL_TYPE)) p.Add("Null"); + if (s.Contains(ToBooleanICStub::SMI)) p.Add("Smi"); + if (s.Contains(ToBooleanICStub::SPEC_OBJECT)) p.Add("SpecObject"); + if (s.Contains(ToBooleanICStub::STRING)) p.Add("String"); + if (s.Contains(ToBooleanICStub::SYMBOL)) p.Add("Symbol"); + if (s.Contains(ToBooleanICStub::HEAP_NUMBER)) p.Add("HeapNumber"); + if (s.Contains(ToBooleanICStub::SIMD_VALUE)) p.Add("SimdValue"); return os << ")"; } - -bool ToBooleanStub::Types::UpdateStatus(Handle object) { +bool ToBooleanICStub::Types::UpdateStatus(Handle object) { if (object->IsUndefined()) { Add(UNDEFINED); return false; @@ -841,12 +974,12 @@ bool ToBooleanStub::Types::UpdateStatus(Handle object) { } } - -bool ToBooleanStub::Types::NeedsMap() const { - return Contains(ToBooleanStub::SPEC_OBJECT) || - Contains(ToBooleanStub::STRING) || Contains(ToBooleanStub::SYMBOL) || - Contains(ToBooleanStub::HEAP_NUMBER) || - Contains(ToBooleanStub::SIMD_VALUE); +bool ToBooleanICStub::Types::NeedsMap() const { + return Contains(ToBooleanICStub::SPEC_OBJECT) || + Contains(ToBooleanICStub::STRING) || + Contains(ToBooleanICStub::SYMBOL) || + Contains(ToBooleanICStub::HEAP_NUMBER) || + Contains(ToBooleanICStub::SIMD_VALUE); } diff --git a/src/code-stubs.h b/src/code-stubs.h index 4f3020ed5d..ce4e944514 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -95,12 +95,13 @@ namespace internal { V(StoreGlobalViaContext) \ V(StoreScriptContextField) \ V(StringAdd) \ - V(ToBoolean) \ + V(ToBooleanIC) \ V(TransitionElementsKind) \ V(KeyedLoadIC) \ V(LoadIC) \ /* TurboFanCodeStubs */ \ V(StringLength) \ + V(ToBoolean) \ /* IC Handler stubs */ \ V(ArrayBufferViewLoadField) \ V(LoadConstant) \ @@ -630,6 +631,15 @@ class StringLengthStub : public TurboFanCodeStub { DEFINE_CODE_STUB(StringLength, TurboFanCodeStub); }; +class ToBooleanStub final : public TurboFanCodeStub { + public: + explicit ToBooleanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {} + + void GenerateAssembly(compiler::CodeStubAssembler* assembler) const final; + + DEFINE_CALL_INTERFACE_DESCRIPTOR(ToBoolean); + DEFINE_CODE_STUB(ToBoolean, TurboFanCodeStub); +}; enum StringAddFlags { // Omit both parameter checks. @@ -2636,8 +2646,7 @@ class StoreElementStub : public PlatformCodeStub { DEFINE_PLATFORM_CODE_STUB(StoreElement, PlatformCodeStub); }; - -class ToBooleanStub: public HydrogenCodeStub { +class ToBooleanICStub : public HydrogenCodeStub { public: enum Type { UNDEFINED, @@ -2664,14 +2673,14 @@ class ToBooleanStub: public HydrogenCodeStub { bool UpdateStatus(Handle object); bool NeedsMap() const; bool CanBeUndetectable() const { - return Contains(ToBooleanStub::SPEC_OBJECT); + return Contains(ToBooleanICStub::SPEC_OBJECT); } bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); } static Types Generic() { return Types((1 << NUMBER_OF_TYPES) - 1); } }; - ToBooleanStub(Isolate* isolate, ExtraICState state) + ToBooleanICStub(Isolate* isolate, ExtraICState state) : HydrogenCodeStub(isolate) { set_sub_minor_key(TypesBits::encode(static_cast(state))); } @@ -2685,7 +2694,7 @@ class ToBooleanStub: public HydrogenCodeStub { bool SometimesSetsUpAFrame() override { return false; } static Handle GetUninitialized(Isolate* isolate) { - return ToBooleanStub(isolate, UNINITIALIZED).GetCode(); + return ToBooleanICStub(isolate, UNINITIALIZED).GetCode(); } ExtraICState GetExtraICState() const override { return types().ToIntegral(); } @@ -2699,19 +2708,16 @@ class ToBooleanStub: public HydrogenCodeStub { } private: - ToBooleanStub(Isolate* isolate, InitializationState init_state) - : HydrogenCodeStub(isolate, init_state) { - } + ToBooleanICStub(Isolate* isolate, InitializationState init_state) + : HydrogenCodeStub(isolate, init_state) {} class TypesBits : public BitField {}; DEFINE_CALL_INTERFACE_DESCRIPTOR(ToBoolean); - DEFINE_HYDROGEN_CODE_STUB(ToBoolean, HydrogenCodeStub); + DEFINE_HYDROGEN_CODE_STUB(ToBooleanIC, HydrogenCodeStub); }; - -std::ostream& operator<<(std::ostream& os, const ToBooleanStub::Types& t); - +std::ostream& operator<<(std::ostream& os, const ToBooleanICStub::Types& t); class ElementsTransitionAndStoreStub : public HydrogenCodeStub { public: diff --git a/src/compiler/code-stub-assembler.cc b/src/compiler/code-stub-assembler.cc index 52d506679c..3f81657882 100644 --- a/src/compiler/code-stub-assembler.cc +++ b/src/compiler/code-stub-assembler.cc @@ -89,6 +89,10 @@ Node* CodeStubAssembler::ExternalConstant(ExternalReference address) { return raw_assembler_->ExternalConstant(address); } +Node* CodeStubAssembler::Float64Constant(double value) { + return raw_assembler_->Float64Constant(value); +} + Node* CodeStubAssembler::Parameter(int value) { return raw_assembler_->Parameter(value); } @@ -130,6 +134,8 @@ Node* CodeStubAssembler::SmiUntag(Node* value) { Node* CodeStubAssembler::SmiAdd(Node* a, Node* b) { return IntPtrAdd(a, b); } +Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { return WordEqual(a, b); } + #define DEFINE_CODE_STUB_ASSEMBER_BINARY_OP(name) \ Node* CodeStubAssembler::name(Node* a, Node* b) { \ return raw_assembler_->name(a, b); \ diff --git a/src/compiler/code-stub-assembler.h b/src/compiler/code-stub-assembler.h index f8723beb24..4d52065fcf 100644 --- a/src/compiler/code-stub-assembler.h +++ b/src/compiler/code-stub-assembler.h @@ -34,6 +34,9 @@ class RawMachineLabel; class Schedule; #define CODE_STUB_ASSEMBLER_BINARY_OP_LIST(V) \ + V(Float64Equal) \ + V(Float64LessThan) \ + V(Float64LessThanOrEqual) \ V(IntPtrAdd) \ V(IntPtrSub) \ V(Int32Add) \ @@ -107,6 +110,7 @@ class CodeStubAssembler { Node* HeapConstant(Handle object); Node* BooleanConstant(bool value); Node* ExternalConstant(ExternalReference address); + Node* Float64Constant(double value); Node* Parameter(int value); void Return(Node* value); @@ -197,7 +201,8 @@ class CodeStubAssembler { Node* SmiUntag(Node* value); // Smi operations. - Node* SmiAdd(Node* lhs, Node* rhs); + Node* SmiAdd(Node* a, Node* b); + Node* SmiEqual(Node* a, Node* b); // Load a value from the root array. Node* LoadRoot(Heap::RootListIndex root_index); diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc index 64d435ff9c..59f67cb05e 100644 --- a/src/compiler/js-generic-lowering.cc +++ b/src/compiler/js-generic-lowering.cc @@ -139,8 +139,7 @@ void JSGenericLowering::LowerJSTypeOf(Node* node) { void JSGenericLowering::LowerJSToBoolean(Node* node) { CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); Callable callable = CodeFactory::ToBoolean(isolate()); - ReplaceWithStubCall(node, callable, - CallDescriptor::kPatchableCallSite | flags); + ReplaceWithStubCall(node, callable, flags); } diff --git a/src/compiler/linkage.cc b/src/compiler/linkage.cc index fbe607bc6d..67c8f1faa4 100644 --- a/src/compiler/linkage.cc +++ b/src/compiler/linkage.cc @@ -400,7 +400,8 @@ CallDescriptor* Linkage::GetStubCallDescriptor( properties, // properties kNoCalleeSaved, // callee-saved registers kNoCalleeSaved, // callee-saved fp - flags, // flags + CallDescriptor::kCanUseRoots | // flags + flags, // flags descriptor.DebugName(isolate)); } diff --git a/src/compiler/mips/instruction-selector-mips.cc b/src/compiler/mips/instruction-selector-mips.cc index 6bd836a6e4..b4ba49758b 100644 --- a/src/compiler/mips/instruction-selector-mips.cc +++ b/src/compiler/mips/instruction-selector-mips.cc @@ -1214,23 +1214,27 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { MipsOperandGenerator g(this); InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); - // Emit either ArchTableSwitch or ArchLookupSwitch. - size_t table_space_cost = 9 + sw.value_range; - size_t table_time_cost = 3; - size_t lookup_space_cost = 2 + 2 * sw.case_count; - size_t lookup_time_cost = sw.case_count; - if (sw.case_count > 0 && - table_space_cost + 3 * table_time_cost <= - lookup_space_cost + 3 * lookup_time_cost && - sw.min_value > std::numeric_limits::min()) { - InstructionOperand index_operand = value_operand; - if (sw.min_value) { - index_operand = g.TempRegister(); - Emit(kMipsSub, index_operand, value_operand, - g.TempImmediate(sw.min_value)); + // TODO(mips): TableSwitch is broken, as it messes with ra without saving it + // properly (which breaks with frame elision, i.e. inside stubs). + if (false) { + // Emit either ArchTableSwitch or ArchLookupSwitch. + size_t table_space_cost = 9 + sw.value_range; + size_t table_time_cost = 3; + size_t lookup_space_cost = 2 + 2 * sw.case_count; + size_t lookup_time_cost = sw.case_count; + if (sw.case_count > 0 && + table_space_cost + 3 * table_time_cost <= + lookup_space_cost + 3 * lookup_time_cost && + sw.min_value > std::numeric_limits::min()) { + InstructionOperand index_operand = value_operand; + if (sw.min_value) { + index_operand = g.TempRegister(); + Emit(kMipsSub, index_operand, value_operand, + g.TempImmediate(sw.min_value)); + } + // Generate a table lookup. + return EmitTableSwitch(sw, index_operand); } - // Generate a table lookup. - return EmitTableSwitch(sw, index_operand); } // Generate a sequence of conditional jumps. diff --git a/src/compiler/mips64/instruction-selector-mips64.cc b/src/compiler/mips64/instruction-selector-mips64.cc index 56188f1817..eae2d3170d 100644 --- a/src/compiler/mips64/instruction-selector-mips64.cc +++ b/src/compiler/mips64/instruction-selector-mips64.cc @@ -1711,23 +1711,27 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { Mips64OperandGenerator g(this); InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); - // Emit either ArchTableSwitch or ArchLookupSwitch. - size_t table_space_cost = 10 + 2 * sw.value_range; - size_t table_time_cost = 3; - size_t lookup_space_cost = 2 + 2 * sw.case_count; - size_t lookup_time_cost = sw.case_count; - if (sw.case_count > 0 && - table_space_cost + 3 * table_time_cost <= - lookup_space_cost + 3 * lookup_time_cost && - sw.min_value > std::numeric_limits::min()) { - InstructionOperand index_operand = value_operand; - if (sw.min_value) { - index_operand = g.TempRegister(); - Emit(kMips64Sub, index_operand, value_operand, - g.TempImmediate(sw.min_value)); + // TODO(mips): TableSwitch is broken, as it messes with ra without saving it + // properly (which breaks with frame elision, i.e. inside stubs). + if (false) { + // Emit either ArchTableSwitch or ArchLookupSwitch. + size_t table_space_cost = 10 + 2 * sw.value_range; + size_t table_time_cost = 3; + size_t lookup_space_cost = 2 + 2 * sw.case_count; + size_t lookup_time_cost = sw.case_count; + if (sw.case_count > 0 && + table_space_cost + 3 * table_time_cost <= + lookup_space_cost + 3 * lookup_time_cost && + sw.min_value > std::numeric_limits::min()) { + InstructionOperand index_operand = value_operand; + if (sw.min_value) { + index_operand = g.TempRegister(); + Emit(kMips64Sub, index_operand, value_operand, + g.TempImmediate(sw.min_value)); + } + // Generate a table lookup. + return EmitTableSwitch(sw, index_operand); } - // Generate a table lookup. - return EmitTableSwitch(sw, index_operand); } // Generate a sequence of conditional jumps. diff --git a/src/compiler/type-hint-analyzer.cc b/src/compiler/type-hint-analyzer.cc index 42c4627b67..da4f2683a3 100644 --- a/src/compiler/type-hint-analyzer.cc +++ b/src/compiler/type-hint-analyzer.cc @@ -48,10 +48,10 @@ bool TypeHintAnalysis::GetToBooleanHints(TypeFeedbackId id, if (i == infos_.end()) return false; Handle code = i->second; DCHECK_EQ(Code::TO_BOOLEAN_IC, code->kind()); - ToBooleanStub stub(code->GetIsolate(), code->extra_ic_state()); -// TODO(bmeurer): Replace ToBooleanStub::Types with ToBooleanHints. -#define ASSERT_COMPATIBLE(NAME, Name) \ - STATIC_ASSERT(1 << ToBooleanStub::NAME == \ + ToBooleanICStub stub(code->GetIsolate(), code->extra_ic_state()); +// TODO(bmeurer): Replace ToBooleanICStub::Types with ToBooleanHints. +#define ASSERT_COMPATIBLE(NAME, Name) \ + STATIC_ASSERT(1 << ToBooleanICStub::NAME == \ static_cast(ToBooleanHint::k##Name)) ASSERT_COMPATIBLE(UNDEFINED, Undefined); ASSERT_COMPATIBLE(BOOLEAN, Boolean); diff --git a/src/crankshaft/arm/lithium-arm.cc b/src/crankshaft/arm/lithium-arm.cc index a05194f86d..e32e7e6bb0 100644 --- a/src/crankshaft/arm/lithium-arm.cc +++ b/src/crankshaft/arm/lithium-arm.cc @@ -904,14 +904,14 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { HValue* value = instr->value(); Representation r = value->representation(); HType type = value->type(); - ToBooleanStub::Types expected = instr->expected_input_types(); - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + ToBooleanICStub::Types expected = instr->expected_input_types(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || type.IsJSArray() || type.IsHeapNumber() || type.IsString(); LInstruction* branch = new(zone()) LBranch(UseRegister(value)); if (!easy_case && - ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || + ((!expected.Contains(ToBooleanICStub::SMI) && expected.NeedsMap()) || !expected.IsGeneric())) { branch = AssignEnvironment(branch); } diff --git a/src/crankshaft/arm/lithium-codegen-arm.cc b/src/crankshaft/arm/lithium-codegen-arm.cc index 4634fcc9d4..568efe83ae 100644 --- a/src/crankshaft/arm/lithium-codegen-arm.cc +++ b/src/crankshaft/arm/lithium-codegen-arm.cc @@ -2070,29 +2070,30 @@ void LCodeGen::DoBranch(LBranch* instr) { __ cmp(ip, Operand::Zero()); EmitBranch(instr, ne); } else { - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); + ToBooleanICStub::Types expected = + instr->hydrogen()->expected_input_types(); // Avoid deopts in the case where we've never executed this path before. - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); - if (expected.Contains(ToBooleanStub::UNDEFINED)) { + if (expected.Contains(ToBooleanICStub::UNDEFINED)) { // undefined -> false. __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); __ b(eq, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::BOOLEAN)) { + if (expected.Contains(ToBooleanICStub::BOOLEAN)) { // Boolean -> its value. __ CompareRoot(reg, Heap::kTrueValueRootIndex); __ b(eq, instr->TrueLabel(chunk_)); __ CompareRoot(reg, Heap::kFalseValueRootIndex); __ b(eq, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::NULL_TYPE)) { + if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { // 'null' -> false. __ CompareRoot(reg, Heap::kNullValueRootIndex); __ b(eq, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::SMI)) { + if (expected.Contains(ToBooleanICStub::SMI)) { // Smis: 0 -> false, all other -> true. __ cmp(reg, Operand::Zero()); __ b(eq, instr->FalseLabel(chunk_)); @@ -2115,13 +2116,13 @@ void LCodeGen::DoBranch(LBranch* instr) { } } - if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { + if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { // spec object -> true. __ CompareInstanceType(map, ip, FIRST_JS_RECEIVER_TYPE); __ b(ge, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::STRING)) { + if (expected.Contains(ToBooleanICStub::STRING)) { // String value -> false iff empty. Label not_string; __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); @@ -2133,19 +2134,19 @@ void LCodeGen::DoBranch(LBranch* instr) { __ bind(¬_string); } - if (expected.Contains(ToBooleanStub::SYMBOL)) { + if (expected.Contains(ToBooleanICStub::SYMBOL)) { // Symbol value -> true. __ CompareInstanceType(map, ip, SYMBOL_TYPE); __ b(eq, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { + if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { // SIMD value -> true. __ CompareInstanceType(map, ip, SIMD128_VALUE_TYPE); __ b(eq, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { + if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { // heap number -> false iff +0, -0, or NaN. DwVfpRegister dbl_scratch = double_scratch0(); Label not_heap_number; diff --git a/src/crankshaft/arm64/lithium-arm64.cc b/src/crankshaft/arm64/lithium-arm64.cc index 39381d87bf..603cbacc4b 100644 --- a/src/crankshaft/arm64/lithium-arm64.cc +++ b/src/crankshaft/arm64/lithium-arm64.cc @@ -972,7 +972,7 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { return new(zone()) LBranch(UseRegister(value), TempRegister(), NULL); } - ToBooleanStub::Types expected = instr->expected_input_types(); + ToBooleanICStub::Types expected = instr->expected_input_types(); bool needs_temps = expected.NeedsMap() || expected.IsEmpty(); LOperand* temp1 = needs_temps ? TempRegister() : NULL; LOperand* temp2 = needs_temps ? TempRegister() : NULL; diff --git a/src/crankshaft/arm64/lithium-codegen-arm64.cc b/src/crankshaft/arm64/lithium-codegen-arm64.cc index 43b52c40fa..abb0e71ea4 100644 --- a/src/crankshaft/arm64/lithium-codegen-arm64.cc +++ b/src/crankshaft/arm64/lithium-codegen-arm64.cc @@ -1731,17 +1731,18 @@ void LCodeGen::DoBranch(LBranch* instr) { __ Ldr(temp, FieldMemOperand(value, String::kLengthOffset)); EmitCompareAndBranch(instr, ne, temp, 0); } else { - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); + ToBooleanICStub::Types expected = + instr->hydrogen()->expected_input_types(); // Avoid deopts in the case where we've never executed this path before. - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); - if (expected.Contains(ToBooleanStub::UNDEFINED)) { + if (expected.Contains(ToBooleanICStub::UNDEFINED)) { // undefined -> false. __ JumpIfRoot( value, Heap::kUndefinedValueRootIndex, false_label); } - if (expected.Contains(ToBooleanStub::BOOLEAN)) { + if (expected.Contains(ToBooleanICStub::BOOLEAN)) { // Boolean -> its value. __ JumpIfRoot( value, Heap::kTrueValueRootIndex, true_label); @@ -1749,13 +1750,13 @@ void LCodeGen::DoBranch(LBranch* instr) { value, Heap::kFalseValueRootIndex, false_label); } - if (expected.Contains(ToBooleanStub::NULL_TYPE)) { + if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { // 'null' -> false. __ JumpIfRoot( value, Heap::kNullValueRootIndex, false_label); } - if (expected.Contains(ToBooleanStub::SMI)) { + if (expected.Contains(ToBooleanICStub::SMI)) { // Smis: 0 -> false, all other -> true. DCHECK(Smi::FromInt(0) == 0); __ Cbz(value, false_label); @@ -1783,13 +1784,13 @@ void LCodeGen::DoBranch(LBranch* instr) { } } - if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { + if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { // spec object -> true. __ CompareInstanceType(map, scratch, FIRST_JS_RECEIVER_TYPE); __ B(ge, true_label); } - if (expected.Contains(ToBooleanStub::STRING)) { + if (expected.Contains(ToBooleanICStub::STRING)) { // String value -> false iff empty. Label not_string; __ CompareInstanceType(map, scratch, FIRST_NONSTRING_TYPE); @@ -1800,19 +1801,19 @@ void LCodeGen::DoBranch(LBranch* instr) { __ Bind(¬_string); } - if (expected.Contains(ToBooleanStub::SYMBOL)) { + if (expected.Contains(ToBooleanICStub::SYMBOL)) { // Symbol value -> true. __ CompareInstanceType(map, scratch, SYMBOL_TYPE); __ B(eq, true_label); } - if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { + if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { // SIMD value -> true. __ CompareInstanceType(map, scratch, SIMD128_VALUE_TYPE); __ B(eq, true_label); } - if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { + if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { Label not_heap_number; __ JumpIfNotRoot(map, Heap::kHeapNumberMapRootIndex, ¬_heap_number); diff --git a/src/crankshaft/hydrogen-instructions.cc b/src/crankshaft/hydrogen-instructions.cc index 3c3ae355ae..1a82a0fa84 100644 --- a/src/crankshaft/hydrogen-instructions.cc +++ b/src/crankshaft/hydrogen-instructions.cc @@ -1095,23 +1095,23 @@ std::ostream& HReturn::PrintDataTo(std::ostream& os) const { // NOLINT Representation HBranch::observed_input_representation(int index) { - if (expected_input_types_.Contains(ToBooleanStub::NULL_TYPE) || - expected_input_types_.Contains(ToBooleanStub::SPEC_OBJECT) || - expected_input_types_.Contains(ToBooleanStub::STRING) || - expected_input_types_.Contains(ToBooleanStub::SYMBOL) || - expected_input_types_.Contains(ToBooleanStub::SIMD_VALUE)) { + if (expected_input_types_.Contains(ToBooleanICStub::NULL_TYPE) || + expected_input_types_.Contains(ToBooleanICStub::SPEC_OBJECT) || + expected_input_types_.Contains(ToBooleanICStub::STRING) || + expected_input_types_.Contains(ToBooleanICStub::SYMBOL) || + expected_input_types_.Contains(ToBooleanICStub::SIMD_VALUE)) { return Representation::Tagged(); } - if (expected_input_types_.Contains(ToBooleanStub::UNDEFINED)) { - if (expected_input_types_.Contains(ToBooleanStub::HEAP_NUMBER)) { + if (expected_input_types_.Contains(ToBooleanICStub::UNDEFINED)) { + if (expected_input_types_.Contains(ToBooleanICStub::HEAP_NUMBER)) { return Representation::Double(); } return Representation::Tagged(); } - if (expected_input_types_.Contains(ToBooleanStub::HEAP_NUMBER)) { + if (expected_input_types_.Contains(ToBooleanICStub::HEAP_NUMBER)) { return Representation::Double(); } - if (expected_input_types_.Contains(ToBooleanStub::SMI)) { + if (expected_input_types_.Contains(ToBooleanICStub::SMI)) { return Representation::Smi(); } return Representation::None(); diff --git a/src/crankshaft/hydrogen-instructions.h b/src/crankshaft/hydrogen-instructions.h index 710e0b174c..da21400cea 100644 --- a/src/crankshaft/hydrogen-instructions.h +++ b/src/crankshaft/hydrogen-instructions.h @@ -1366,10 +1366,8 @@ class HUnaryControlInstruction : public HTemplateControlInstruction<2, 1> { class HBranch final : public HUnaryControlInstruction { public: DECLARE_INSTRUCTION_FACTORY_P1(HBranch, HValue*); - DECLARE_INSTRUCTION_FACTORY_P2(HBranch, HValue*, - ToBooleanStub::Types); - DECLARE_INSTRUCTION_FACTORY_P4(HBranch, HValue*, - ToBooleanStub::Types, + DECLARE_INSTRUCTION_FACTORY_P2(HBranch, HValue*, ToBooleanICStub::Types); + DECLARE_INSTRUCTION_FACTORY_P4(HBranch, HValue*, ToBooleanICStub::Types, HBasicBlock*, HBasicBlock*); Representation RequiredInputRepresentation(int index) override { @@ -1381,23 +1379,22 @@ class HBranch final : public HUnaryControlInstruction { std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT - ToBooleanStub::Types expected_input_types() const { + ToBooleanICStub::Types expected_input_types() const { return expected_input_types_; } DECLARE_CONCRETE_INSTRUCTION(Branch) private: - HBranch(HValue* value, - ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(), - HBasicBlock* true_target = NULL, - HBasicBlock* false_target = NULL) + HBranch(HValue* value, ToBooleanICStub::Types expected_input_types = + ToBooleanICStub::Types(), + HBasicBlock* true_target = NULL, HBasicBlock* false_target = NULL) : HUnaryControlInstruction(value, true_target, false_target), expected_input_types_(expected_input_types) { SetFlag(kAllowUndefinedAsNaN); } - ToBooleanStub::Types expected_input_types_; + ToBooleanICStub::Types expected_input_types_; }; diff --git a/src/crankshaft/hydrogen-osr.cc b/src/crankshaft/hydrogen-osr.cc index c98bbf627f..8de3ac0705 100644 --- a/src/crankshaft/hydrogen-osr.cc +++ b/src/crankshaft/hydrogen-osr.cc @@ -30,7 +30,7 @@ HBasicBlock* HOsrBuilder::BuildOsrLoopEntry(IterationStatement* statement) { HBasicBlock* non_osr_entry = graph->CreateBasicBlock(); osr_entry_ = graph->CreateBasicBlock(); HValue* true_value = graph->GetConstantTrue(); - HBranch* test = builder_->New(true_value, ToBooleanStub::Types(), + HBranch* test = builder_->New(true_value, ToBooleanICStub::Types(), non_osr_entry, osr_entry_); builder_->FinishCurrentBlock(test); diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc index 11d054c3e9..8ff3f3ba3f 100644 --- a/src/crankshaft/hydrogen.cc +++ b/src/crankshaft/hydrogen.cc @@ -906,8 +906,8 @@ void HGraphBuilder::IfBuilder::Then() { // so that the graph builder visits it and sees any live range extending // constructs within it. HConstant* constant_false = builder()->graph()->GetConstantFalse(); - ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); - boolean_type.Add(ToBooleanStub::BOOLEAN); + ToBooleanICStub::Types boolean_type = ToBooleanICStub::Types(); + boolean_type.Add(ToBooleanICStub::BOOLEAN); HBranch* branch = builder()->New( constant_false, boolean_type, first_true_block_, first_false_block_); builder()->FinishCurrentBlock(branch); @@ -4298,7 +4298,7 @@ void TestContext::BuildBranch(HValue* value) { if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { builder->Bailout(kArgumentsObjectValueInATestContext); } - ToBooleanStub::Types expected(condition()->to_boolean_types()); + ToBooleanICStub::Types expected(condition()->to_boolean_types()); ReturnControl(owner()->New(value, expected), BailoutId::None()); } @@ -11293,7 +11293,7 @@ void HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { // We need an extra block to maintain edge-split form. HBasicBlock* empty_block = graph()->CreateBasicBlock(); HBasicBlock* eval_right = graph()->CreateBasicBlock(); - ToBooleanStub::Types expected(expr->left()->to_boolean_types()); + ToBooleanICStub::Types expected(expr->left()->to_boolean_types()); HBranch* test = is_logical_and ? New(left_value, expected, eval_right, empty_block) : New(left_value, expected, empty_block, eval_right); diff --git a/src/crankshaft/ia32/lithium-codegen-ia32.cc b/src/crankshaft/ia32/lithium-codegen-ia32.cc index ad10da5601..f292b949da 100644 --- a/src/crankshaft/ia32/lithium-codegen-ia32.cc +++ b/src/crankshaft/ia32/lithium-codegen-ia32.cc @@ -1869,15 +1869,16 @@ void LCodeGen::DoBranch(LBranch* instr) { __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); EmitBranch(instr, not_equal); } else { - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + ToBooleanICStub::Types expected = + instr->hydrogen()->expected_input_types(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); - if (expected.Contains(ToBooleanStub::UNDEFINED)) { + if (expected.Contains(ToBooleanICStub::UNDEFINED)) { // undefined -> false. __ cmp(reg, factory()->undefined_value()); __ j(equal, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::BOOLEAN)) { + if (expected.Contains(ToBooleanICStub::BOOLEAN)) { // true -> true. __ cmp(reg, factory()->true_value()); __ j(equal, instr->TrueLabel(chunk_)); @@ -1885,13 +1886,13 @@ void LCodeGen::DoBranch(LBranch* instr) { __ cmp(reg, factory()->false_value()); __ j(equal, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::NULL_TYPE)) { + if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { // 'null' -> false. __ cmp(reg, factory()->null_value()); __ j(equal, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::SMI)) { + if (expected.Contains(ToBooleanICStub::SMI)) { // Smis: 0 -> false, all other -> true. __ test(reg, Operand(reg)); __ j(equal, instr->FalseLabel(chunk_)); @@ -1916,13 +1917,13 @@ void LCodeGen::DoBranch(LBranch* instr) { } } - if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { + if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { // spec object -> true. __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); __ j(above_equal, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::STRING)) { + if (expected.Contains(ToBooleanICStub::STRING)) { // String value -> false iff empty. Label not_string; __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); @@ -1933,19 +1934,19 @@ void LCodeGen::DoBranch(LBranch* instr) { __ bind(¬_string); } - if (expected.Contains(ToBooleanStub::SYMBOL)) { + if (expected.Contains(ToBooleanICStub::SYMBOL)) { // Symbol value -> true. __ CmpInstanceType(map, SYMBOL_TYPE); __ j(equal, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { + if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { // SIMD value -> true. __ CmpInstanceType(map, SIMD128_VALUE_TYPE); __ j(equal, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { + if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { // heap number -> false iff +0, -0, or NaN. Label not_heap_number; __ cmp(FieldOperand(reg, HeapObject::kMapOffset), diff --git a/src/crankshaft/ia32/lithium-ia32.cc b/src/crankshaft/ia32/lithium-ia32.cc index a7ea51489a..d6117379de 100644 --- a/src/crankshaft/ia32/lithium-ia32.cc +++ b/src/crankshaft/ia32/lithium-ia32.cc @@ -936,15 +936,15 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { HValue* value = instr->value(); Representation r = value->representation(); HType type = value->type(); - ToBooleanStub::Types expected = instr->expected_input_types(); - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + ToBooleanICStub::Types expected = instr->expected_input_types(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || type.IsJSArray() || type.IsHeapNumber() || type.IsString(); LOperand* temp = !easy_case && expected.NeedsMap() ? TempRegister() : NULL; LInstruction* branch = new(zone()) LBranch(UseRegister(value), temp); if (!easy_case && - ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || + ((!expected.Contains(ToBooleanICStub::SMI) && expected.NeedsMap()) || !expected.IsGeneric())) { branch = AssignEnvironment(branch); } diff --git a/src/crankshaft/mips/lithium-codegen-mips.cc b/src/crankshaft/mips/lithium-codegen-mips.cc index 414061d8e3..1073f86af0 100644 --- a/src/crankshaft/mips/lithium-codegen-mips.cc +++ b/src/crankshaft/mips/lithium-codegen-mips.cc @@ -1966,29 +1966,30 @@ void LCodeGen::DoBranch(LBranch* instr) { __ lw(at, FieldMemOperand(reg, String::kLengthOffset)); EmitBranch(instr, ne, at, Operand(zero_reg)); } else { - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); + ToBooleanICStub::Types expected = + instr->hydrogen()->expected_input_types(); // Avoid deopts in the case where we've never executed this path before. - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); - if (expected.Contains(ToBooleanStub::UNDEFINED)) { + if (expected.Contains(ToBooleanICStub::UNDEFINED)) { // undefined -> false. __ LoadRoot(at, Heap::kUndefinedValueRootIndex); __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); } - if (expected.Contains(ToBooleanStub::BOOLEAN)) { + if (expected.Contains(ToBooleanICStub::BOOLEAN)) { // Boolean -> its value. __ LoadRoot(at, Heap::kTrueValueRootIndex); __ Branch(instr->TrueLabel(chunk_), eq, reg, Operand(at)); __ LoadRoot(at, Heap::kFalseValueRootIndex); __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); } - if (expected.Contains(ToBooleanStub::NULL_TYPE)) { + if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { // 'null' -> false. __ LoadRoot(at, Heap::kNullValueRootIndex); __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); } - if (expected.Contains(ToBooleanStub::SMI)) { + if (expected.Contains(ToBooleanICStub::SMI)) { // Smis: 0 -> false, all other -> true. __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg)); __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); @@ -2009,14 +2010,14 @@ void LCodeGen::DoBranch(LBranch* instr) { } } - if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { + if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { // spec object -> true. __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); __ Branch(instr->TrueLabel(chunk_), ge, at, Operand(FIRST_JS_RECEIVER_TYPE)); } - if (expected.Contains(ToBooleanStub::STRING)) { + if (expected.Contains(ToBooleanICStub::STRING)) { // String value -> false iff empty. Label not_string; __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); @@ -2027,14 +2028,14 @@ void LCodeGen::DoBranch(LBranch* instr) { __ bind(¬_string); } - if (expected.Contains(ToBooleanStub::SYMBOL)) { + if (expected.Contains(ToBooleanICStub::SYMBOL)) { // Symbol value -> true. const Register scratch = scratch1(); __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE)); } - if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { + if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { // SIMD value -> true. const Register scratch = scratch1(); __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); @@ -2042,7 +2043,7 @@ void LCodeGen::DoBranch(LBranch* instr) { Operand(SIMD128_VALUE_TYPE)); } - if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { + if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { // heap number -> false iff +0, -0, or NaN. DoubleRegister dbl_scratch = double_scratch0(); Label not_heap_number; diff --git a/src/crankshaft/mips/lithium-mips.cc b/src/crankshaft/mips/lithium-mips.cc index e269be0f12..ddf1ceed96 100644 --- a/src/crankshaft/mips/lithium-mips.cc +++ b/src/crankshaft/mips/lithium-mips.cc @@ -914,14 +914,14 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { HValue* value = instr->value(); Representation r = value->representation(); HType type = value->type(); - ToBooleanStub::Types expected = instr->expected_input_types(); - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + ToBooleanICStub::Types expected = instr->expected_input_types(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || type.IsJSArray() || type.IsHeapNumber() || type.IsString(); LInstruction* branch = new(zone()) LBranch(UseRegister(value)); if (!easy_case && - ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || + ((!expected.Contains(ToBooleanICStub::SMI) && expected.NeedsMap()) || !expected.IsGeneric())) { branch = AssignEnvironment(branch); } diff --git a/src/crankshaft/mips64/lithium-codegen-mips64.cc b/src/crankshaft/mips64/lithium-codegen-mips64.cc index 729bedee5f..f8652ea843 100644 --- a/src/crankshaft/mips64/lithium-codegen-mips64.cc +++ b/src/crankshaft/mips64/lithium-codegen-mips64.cc @@ -2083,29 +2083,30 @@ void LCodeGen::DoBranch(LBranch* instr) { __ ld(at, FieldMemOperand(reg, String::kLengthOffset)); EmitBranch(instr, ne, at, Operand(zero_reg)); } else { - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); + ToBooleanICStub::Types expected = + instr->hydrogen()->expected_input_types(); // Avoid deopts in the case where we've never executed this path before. - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); - if (expected.Contains(ToBooleanStub::UNDEFINED)) { + if (expected.Contains(ToBooleanICStub::UNDEFINED)) { // undefined -> false. __ LoadRoot(at, Heap::kUndefinedValueRootIndex); __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); } - if (expected.Contains(ToBooleanStub::BOOLEAN)) { + if (expected.Contains(ToBooleanICStub::BOOLEAN)) { // Boolean -> its value. __ LoadRoot(at, Heap::kTrueValueRootIndex); __ Branch(instr->TrueLabel(chunk_), eq, reg, Operand(at)); __ LoadRoot(at, Heap::kFalseValueRootIndex); __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); } - if (expected.Contains(ToBooleanStub::NULL_TYPE)) { + if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { // 'null' -> false. __ LoadRoot(at, Heap::kNullValueRootIndex); __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at)); } - if (expected.Contains(ToBooleanStub::SMI)) { + if (expected.Contains(ToBooleanICStub::SMI)) { // Smis: 0 -> false, all other -> true. __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg)); __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); @@ -2126,14 +2127,14 @@ void LCodeGen::DoBranch(LBranch* instr) { } } - if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { + if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { // spec object -> true. __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); __ Branch(instr->TrueLabel(chunk_), ge, at, Operand(FIRST_JS_RECEIVER_TYPE)); } - if (expected.Contains(ToBooleanStub::STRING)) { + if (expected.Contains(ToBooleanICStub::STRING)) { // String value -> false iff empty. Label not_string; __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); @@ -2144,14 +2145,14 @@ void LCodeGen::DoBranch(LBranch* instr) { __ bind(¬_string); } - if (expected.Contains(ToBooleanStub::SYMBOL)) { + if (expected.Contains(ToBooleanICStub::SYMBOL)) { // Symbol value -> true. const Register scratch = scratch1(); __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE)); } - if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { + if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { // SIMD value -> true. const Register scratch = scratch1(); __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); @@ -2159,7 +2160,7 @@ void LCodeGen::DoBranch(LBranch* instr) { Operand(SIMD128_VALUE_TYPE)); } - if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { + if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { // heap number -> false iff +0, -0, or NaN. DoubleRegister dbl_scratch = double_scratch0(); Label not_heap_number; diff --git a/src/crankshaft/mips64/lithium-mips64.cc b/src/crankshaft/mips64/lithium-mips64.cc index fc172d5399..e760531893 100644 --- a/src/crankshaft/mips64/lithium-mips64.cc +++ b/src/crankshaft/mips64/lithium-mips64.cc @@ -914,14 +914,14 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { HValue* value = instr->value(); Representation r = value->representation(); HType type = value->type(); - ToBooleanStub::Types expected = instr->expected_input_types(); - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + ToBooleanICStub::Types expected = instr->expected_input_types(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || type.IsJSArray() || type.IsHeapNumber() || type.IsString(); LInstruction* branch = new(zone()) LBranch(UseRegister(value)); if (!easy_case && - ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || + ((!expected.Contains(ToBooleanICStub::SMI) && expected.NeedsMap()) || !expected.IsGeneric())) { branch = AssignEnvironment(branch); } diff --git a/src/crankshaft/ppc/lithium-codegen-ppc.cc b/src/crankshaft/ppc/lithium-codegen-ppc.cc index af31399d1f..a16c92decb 100644 --- a/src/crankshaft/ppc/lithium-codegen-ppc.cc +++ b/src/crankshaft/ppc/lithium-codegen-ppc.cc @@ -2103,29 +2103,30 @@ void LCodeGen::DoBranch(LBranch* instr) { __ cmpi(ip, Operand::Zero()); EmitBranch(instr, ne); } else { - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); + ToBooleanICStub::Types expected = + instr->hydrogen()->expected_input_types(); // Avoid deopts in the case where we've never executed this path before. - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); - if (expected.Contains(ToBooleanStub::UNDEFINED)) { + if (expected.Contains(ToBooleanICStub::UNDEFINED)) { // undefined -> false. __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); __ beq(instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::BOOLEAN)) { + if (expected.Contains(ToBooleanICStub::BOOLEAN)) { // Boolean -> its value. __ CompareRoot(reg, Heap::kTrueValueRootIndex); __ beq(instr->TrueLabel(chunk_)); __ CompareRoot(reg, Heap::kFalseValueRootIndex); __ beq(instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::NULL_TYPE)) { + if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { // 'null' -> false. __ CompareRoot(reg, Heap::kNullValueRootIndex); __ beq(instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::SMI)) { + if (expected.Contains(ToBooleanICStub::SMI)) { // Smis: 0 -> false, all other -> true. __ cmpi(reg, Operand::Zero()); __ beq(instr->FalseLabel(chunk_)); @@ -2148,13 +2149,13 @@ void LCodeGen::DoBranch(LBranch* instr) { } } - if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { + if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { // spec object -> true. __ CompareInstanceType(map, ip, FIRST_JS_RECEIVER_TYPE); __ bge(instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::STRING)) { + if (expected.Contains(ToBooleanICStub::STRING)) { // String value -> false iff empty. Label not_string; __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); @@ -2166,20 +2167,20 @@ void LCodeGen::DoBranch(LBranch* instr) { __ bind(¬_string); } - if (expected.Contains(ToBooleanStub::SYMBOL)) { + if (expected.Contains(ToBooleanICStub::SYMBOL)) { // Symbol value -> true. __ CompareInstanceType(map, ip, SYMBOL_TYPE); __ beq(instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { + if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { // SIMD value -> true. Label not_simd; __ CompareInstanceType(map, ip, SIMD128_VALUE_TYPE); __ beq(instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { + if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { // heap number -> false iff +0, -0, or NaN. Label not_heap_number; __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); diff --git a/src/crankshaft/ppc/lithium-ppc.cc b/src/crankshaft/ppc/lithium-ppc.cc index 15853fde9d..c43a64dbb4 100644 --- a/src/crankshaft/ppc/lithium-ppc.cc +++ b/src/crankshaft/ppc/lithium-ppc.cc @@ -918,14 +918,14 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { HValue* value = instr->value(); Representation r = value->representation(); HType type = value->type(); - ToBooleanStub::Types expected = instr->expected_input_types(); - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + ToBooleanICStub::Types expected = instr->expected_input_types(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || type.IsJSArray() || type.IsHeapNumber() || type.IsString(); LInstruction* branch = new (zone()) LBranch(UseRegister(value)); if (!easy_case && - ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || + ((!expected.Contains(ToBooleanICStub::SMI) && expected.NeedsMap()) || !expected.IsGeneric())) { branch = AssignEnvironment(branch); } diff --git a/src/crankshaft/x64/lithium-codegen-x64.cc b/src/crankshaft/x64/lithium-codegen-x64.cc index 20a2fffece..35855179df 100644 --- a/src/crankshaft/x64/lithium-codegen-x64.cc +++ b/src/crankshaft/x64/lithium-codegen-x64.cc @@ -2012,16 +2012,17 @@ void LCodeGen::DoBranch(LBranch* instr) { __ cmpp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); EmitBranch(instr, not_equal); } else { - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); + ToBooleanICStub::Types expected = + instr->hydrogen()->expected_input_types(); // Avoid deopts in the case where we've never executed this path before. - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); - if (expected.Contains(ToBooleanStub::UNDEFINED)) { + if (expected.Contains(ToBooleanICStub::UNDEFINED)) { // undefined -> false. __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); __ j(equal, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::BOOLEAN)) { + if (expected.Contains(ToBooleanICStub::BOOLEAN)) { // true -> true. __ CompareRoot(reg, Heap::kTrueValueRootIndex); __ j(equal, instr->TrueLabel(chunk_)); @@ -2029,13 +2030,13 @@ void LCodeGen::DoBranch(LBranch* instr) { __ CompareRoot(reg, Heap::kFalseValueRootIndex); __ j(equal, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::NULL_TYPE)) { + if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { // 'null' -> false. __ CompareRoot(reg, Heap::kNullValueRootIndex); __ j(equal, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::SMI)) { + if (expected.Contains(ToBooleanICStub::SMI)) { // Smis: 0 -> false, all other -> true. __ Cmp(reg, Smi::FromInt(0)); __ j(equal, instr->FalseLabel(chunk_)); @@ -2058,13 +2059,13 @@ void LCodeGen::DoBranch(LBranch* instr) { } } - if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { + if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { // spec object -> true. __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); __ j(above_equal, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::STRING)) { + if (expected.Contains(ToBooleanICStub::STRING)) { // String value -> false iff empty. Label not_string; __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); @@ -2075,19 +2076,19 @@ void LCodeGen::DoBranch(LBranch* instr) { __ bind(¬_string); } - if (expected.Contains(ToBooleanStub::SYMBOL)) { + if (expected.Contains(ToBooleanICStub::SYMBOL)) { // Symbol value -> true. __ CmpInstanceType(map, SYMBOL_TYPE); __ j(equal, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { + if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { // SIMD value -> true. __ CmpInstanceType(map, SIMD128_VALUE_TYPE); __ j(equal, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { + if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { // heap number -> false iff +0, -0, or NaN. Label not_heap_number; __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); diff --git a/src/crankshaft/x64/lithium-x64.cc b/src/crankshaft/x64/lithium-x64.cc index 1a69bc77a8..e15fbca934 100644 --- a/src/crankshaft/x64/lithium-x64.cc +++ b/src/crankshaft/x64/lithium-x64.cc @@ -933,14 +933,14 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { HValue* value = instr->value(); Representation r = value->representation(); HType type = value->type(); - ToBooleanStub::Types expected = instr->expected_input_types(); - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + ToBooleanICStub::Types expected = instr->expected_input_types(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || type.IsJSArray() || type.IsHeapNumber() || type.IsString(); LInstruction* branch = new(zone()) LBranch(UseRegister(value)); if (!easy_case && - ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || + ((!expected.Contains(ToBooleanICStub::SMI) && expected.NeedsMap()) || !expected.IsGeneric())) { branch = AssignEnvironment(branch); } diff --git a/src/crankshaft/x87/lithium-codegen-x87.cc b/src/crankshaft/x87/lithium-codegen-x87.cc index 2b2e20ddd1..e7ced921ef 100644 --- a/src/crankshaft/x87/lithium-codegen-x87.cc +++ b/src/crankshaft/x87/lithium-codegen-x87.cc @@ -2137,15 +2137,16 @@ void LCodeGen::DoBranch(LBranch* instr) { __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); EmitBranch(instr, not_equal); } else { - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + ToBooleanICStub::Types expected = + instr->hydrogen()->expected_input_types(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); - if (expected.Contains(ToBooleanStub::UNDEFINED)) { + if (expected.Contains(ToBooleanICStub::UNDEFINED)) { // undefined -> false. __ cmp(reg, factory()->undefined_value()); __ j(equal, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::BOOLEAN)) { + if (expected.Contains(ToBooleanICStub::BOOLEAN)) { // true -> true. __ cmp(reg, factory()->true_value()); __ j(equal, instr->TrueLabel(chunk_)); @@ -2153,13 +2154,13 @@ void LCodeGen::DoBranch(LBranch* instr) { __ cmp(reg, factory()->false_value()); __ j(equal, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::NULL_TYPE)) { + if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { // 'null' -> false. __ cmp(reg, factory()->null_value()); __ j(equal, instr->FalseLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::SMI)) { + if (expected.Contains(ToBooleanICStub::SMI)) { // Smis: 0 -> false, all other -> true. __ test(reg, Operand(reg)); __ j(equal, instr->FalseLabel(chunk_)); @@ -2184,13 +2185,13 @@ void LCodeGen::DoBranch(LBranch* instr) { } } - if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { + if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { // spec object -> true. __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); __ j(above_equal, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::STRING)) { + if (expected.Contains(ToBooleanICStub::STRING)) { // String value -> false iff empty. Label not_string; __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); @@ -2201,19 +2202,19 @@ void LCodeGen::DoBranch(LBranch* instr) { __ bind(¬_string); } - if (expected.Contains(ToBooleanStub::SYMBOL)) { + if (expected.Contains(ToBooleanICStub::SYMBOL)) { // Symbol value -> true. __ CmpInstanceType(map, SYMBOL_TYPE); __ j(equal, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { + if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { // SIMD value -> true. __ CmpInstanceType(map, SIMD128_VALUE_TYPE); __ j(equal, instr->TrueLabel(chunk_)); } - if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { + if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { // heap number -> false iff +0, -0, or NaN. Label not_heap_number; __ cmp(FieldOperand(reg, HeapObject::kMapOffset), diff --git a/src/crankshaft/x87/lithium-x87.cc b/src/crankshaft/x87/lithium-x87.cc index 409ab88ae0..f021061c56 100644 --- a/src/crankshaft/x87/lithium-x87.cc +++ b/src/crankshaft/x87/lithium-x87.cc @@ -952,8 +952,8 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { HValue* value = instr->value(); Representation r = value->representation(); HType type = value->type(); - ToBooleanStub::Types expected = instr->expected_input_types(); - if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); + ToBooleanICStub::Types expected = instr->expected_input_types(); + if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || type.IsJSArray() || type.IsHeapNumber() || type.IsString(); @@ -962,7 +962,7 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { temp != NULL ? new (zone()) LBranch(UseRegister(value), temp) : new (zone()) LBranch(UseRegisterAtStart(value), temp); if (!easy_case && - ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || + ((!expected.Contains(ToBooleanICStub::SMI) && expected.NeedsMap()) || !expected.IsGeneric())) { branch = AssignEnvironment(branch); } diff --git a/src/factory.cc b/src/factory.cc index 15ddb5ff43..cd4c7d54c9 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -112,12 +112,12 @@ Factory::NewSloppyBlockWithEvalContextExtension( return result; } - Handle Factory::NewOddball(Handle map, const char* to_string, - Handle to_number, + Handle to_number, bool to_boolean, const char* type_of, byte kind) { Handle oddball = New(map, OLD_SPACE); - Oddball::Initialize(isolate(), oddball, to_string, to_number, type_of, kind); + Oddball::Initialize(isolate(), oddball, to_string, to_number, to_boolean, + type_of, kind); return oddball; } diff --git a/src/factory.h b/src/factory.h index dd107d144b..8ffae5a487 100644 --- a/src/factory.h +++ b/src/factory.h @@ -16,8 +16,8 @@ namespace internal { class Factory final { public: Handle NewOddball(Handle map, const char* to_string, - Handle to_number, const char* type_of, - byte kind); + Handle to_number, bool to_boolean, + const char* type_of, byte kind); // Allocates a fixed array initialized with undefined values. Handle NewFixedArray( diff --git a/src/full-codegen/arm/full-codegen-arm.cc b/src/full-codegen/arm/full-codegen-arm.cc index 960c7ccf29..ab0717460d 100644 --- a/src/full-codegen/arm/full-codegen-arm.cc +++ b/src/full-codegen/arm/full-codegen-arm.cc @@ -643,7 +643,7 @@ void FullCodeGenerator::DoTest(Expression* condition, Label* if_true, Label* if_false, Label* fall_through) { - Handle ic = ToBooleanStub::GetUninitialized(isolate()); + Handle ic = ToBooleanICStub::GetUninitialized(isolate()); CallIC(ic, condition->test_id()); __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); Split(eq, if_true, if_false, fall_through); diff --git a/src/full-codegen/arm64/full-codegen-arm64.cc b/src/full-codegen/arm64/full-codegen-arm64.cc index d69e4f2cc5..bc75f4767f 100644 --- a/src/full-codegen/arm64/full-codegen-arm64.cc +++ b/src/full-codegen/arm64/full-codegen-arm64.cc @@ -640,7 +640,7 @@ void FullCodeGenerator::DoTest(Expression* condition, Label* if_true, Label* if_false, Label* fall_through) { - Handle ic = ToBooleanStub::GetUninitialized(isolate()); + Handle ic = ToBooleanICStub::GetUninitialized(isolate()); CallIC(ic, condition->test_id()); __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); Split(eq, if_true, if_false, fall_through); diff --git a/src/full-codegen/ia32/full-codegen-ia32.cc b/src/full-codegen/ia32/full-codegen-ia32.cc index aea0515cd9..8ad443ebc8 100644 --- a/src/full-codegen/ia32/full-codegen-ia32.cc +++ b/src/full-codegen/ia32/full-codegen-ia32.cc @@ -595,7 +595,7 @@ void FullCodeGenerator::DoTest(Expression* condition, Label* if_true, Label* if_false, Label* fall_through) { - Handle ic = ToBooleanStub::GetUninitialized(isolate()); + Handle ic = ToBooleanICStub::GetUninitialized(isolate()); CallIC(ic, condition->test_id()); __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); Split(equal, if_true, if_false, fall_through); diff --git a/src/full-codegen/mips/full-codegen-mips.cc b/src/full-codegen/mips/full-codegen-mips.cc index 1c71e8b450..be117a733d 100644 --- a/src/full-codegen/mips/full-codegen-mips.cc +++ b/src/full-codegen/mips/full-codegen-mips.cc @@ -637,7 +637,7 @@ void FullCodeGenerator::DoTest(Expression* condition, Label* if_false, Label* fall_through) { __ mov(a0, result_register()); - Handle ic = ToBooleanStub::GetUninitialized(isolate()); + Handle ic = ToBooleanICStub::GetUninitialized(isolate()); CallIC(ic, condition->test_id()); __ LoadRoot(at, Heap::kTrueValueRootIndex); Split(eq, result_register(), Operand(at), if_true, if_false, fall_through); diff --git a/src/full-codegen/mips64/full-codegen-mips64.cc b/src/full-codegen/mips64/full-codegen-mips64.cc index 334b28be8e..51d839f571 100644 --- a/src/full-codegen/mips64/full-codegen-mips64.cc +++ b/src/full-codegen/mips64/full-codegen-mips64.cc @@ -637,7 +637,7 @@ void FullCodeGenerator::DoTest(Expression* condition, Label* if_false, Label* fall_through) { __ mov(a0, result_register()); - Handle ic = ToBooleanStub::GetUninitialized(isolate()); + Handle ic = ToBooleanICStub::GetUninitialized(isolate()); CallIC(ic, condition->test_id()); __ LoadRoot(at, Heap::kTrueValueRootIndex); Split(eq, result_register(), Operand(at), if_true, if_false, fall_through); diff --git a/src/full-codegen/ppc/full-codegen-ppc.cc b/src/full-codegen/ppc/full-codegen-ppc.cc index 77c75d181e..7fd6e2c7cd 100644 --- a/src/full-codegen/ppc/full-codegen-ppc.cc +++ b/src/full-codegen/ppc/full-codegen-ppc.cc @@ -616,7 +616,7 @@ void FullCodeGenerator::TestContext::Plug(bool flag) const { void FullCodeGenerator::DoTest(Expression* condition, Label* if_true, Label* if_false, Label* fall_through) { - Handle ic = ToBooleanStub::GetUninitialized(isolate()); + Handle ic = ToBooleanICStub::GetUninitialized(isolate()); CallIC(ic, condition->test_id()); __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); Split(eq, if_true, if_false, fall_through); diff --git a/src/full-codegen/x64/full-codegen-x64.cc b/src/full-codegen/x64/full-codegen-x64.cc index d65ab33ebc..5cf4ce01d4 100644 --- a/src/full-codegen/x64/full-codegen-x64.cc +++ b/src/full-codegen/x64/full-codegen-x64.cc @@ -606,7 +606,7 @@ void FullCodeGenerator::DoTest(Expression* condition, Label* if_true, Label* if_false, Label* fall_through) { - Handle ic = ToBooleanStub::GetUninitialized(isolate()); + Handle ic = ToBooleanICStub::GetUninitialized(isolate()); CallIC(ic, condition->test_id()); __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); Split(equal, if_true, if_false, fall_through); diff --git a/src/full-codegen/x87/full-codegen-x87.cc b/src/full-codegen/x87/full-codegen-x87.cc index b1bee84877..a59dda583d 100644 --- a/src/full-codegen/x87/full-codegen-x87.cc +++ b/src/full-codegen/x87/full-codegen-x87.cc @@ -592,7 +592,7 @@ void FullCodeGenerator::DoTest(Expression* condition, Label* if_true, Label* if_false, Label* fall_through) { - Handle ic = ToBooleanStub::GetUninitialized(isolate()); + Handle ic = ToBooleanICStub::GetUninitialized(isolate()); CallIC(ic, condition->test_id()); __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); Split(equal, if_true, if_false, fall_through); diff --git a/src/heap/heap-inl.h b/src/heap/heap-inl.h index 57e6cc4c93..1480da3410 100644 --- a/src/heap/heap-inl.h +++ b/src/heap/heap-inl.h @@ -655,8 +655,7 @@ void Heap::ClearInstanceofCache() { set_instanceof_cache_function(Smi::FromInt(0)); } - -Object* Heap::ToBoolean(bool condition) { +Oddball* Heap::ToBoolean(bool condition) { return condition ? true_value() : false_value(); } diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 2c7a1d0d29..3b5ee6e81b 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -2403,6 +2403,20 @@ bool Heap::CreateInitialMaps() { #undef ALLOCATE_MAP } + { + AllocationResult allocation = Allocate(boolean_map(), OLD_SPACE); + if (!allocation.To(&obj)) return false; + } + set_true_value(Oddball::cast(obj)); + Oddball::cast(obj)->set_kind(Oddball::kTrue); + + { + AllocationResult allocation = Allocate(boolean_map(), OLD_SPACE); + if (!allocation.To(&obj)) return false; + } + set_false_value(Oddball::cast(obj)); + Oddball::cast(obj)->set_kind(Oddball::kFalse); + { // Empty arrays { ByteArray* byte_array; @@ -2620,48 +2634,54 @@ void Heap::CreateInitialObjects() { // Allocate initial string table. set_string_table(*StringTable::New(isolate(), kInitialStringTableSize)); + // Allocate + // Finish initializing oddballs after creating the string table. Oddball::Initialize(isolate(), factory->undefined_value(), "undefined", - factory->nan_value(), "undefined", Oddball::kUndefined); + factory->nan_value(), false, "undefined", + Oddball::kUndefined); // Initialize the null_value. Oddball::Initialize(isolate(), factory->null_value(), "null", - handle(Smi::FromInt(0), isolate()), "object", + handle(Smi::FromInt(0), isolate()), false, "object", Oddball::kNull); - set_true_value(*factory->NewOddball(factory->boolean_map(), "true", - handle(Smi::FromInt(1), isolate()), - "boolean", Oddball::kTrue)); + // Initialize the true_value. + Oddball::Initialize(isolate(), factory->true_value(), "true", + handle(Smi::FromInt(1), isolate()), true, "boolean", + Oddball::kTrue); - set_false_value(*factory->NewOddball(factory->boolean_map(), "false", - handle(Smi::FromInt(0), isolate()), - "boolean", Oddball::kFalse)); + // Initialize the false_value. + Oddball::Initialize(isolate(), factory->false_value(), "false", + handle(Smi::FromInt(0), isolate()), false, "boolean", + Oddball::kFalse); - set_the_hole_value(*factory->NewOddball(factory->the_hole_map(), "hole", - handle(Smi::FromInt(-1), isolate()), - "undefined", Oddball::kTheHole)); + set_the_hole_value(*factory->NewOddball( + factory->the_hole_map(), "hole", handle(Smi::FromInt(-1), isolate()), + false, "undefined", Oddball::kTheHole)); set_uninitialized_value( *factory->NewOddball(factory->uninitialized_map(), "uninitialized", - handle(Smi::FromInt(-1), isolate()), "undefined", - Oddball::kUninitialized)); + handle(Smi::FromInt(-1), isolate()), false, + "undefined", Oddball::kUninitialized)); set_arguments_marker( *factory->NewOddball(factory->arguments_marker_map(), "arguments_marker", - handle(Smi::FromInt(-4), isolate()), "undefined", - Oddball::kArgumentsMarker)); + handle(Smi::FromInt(-4), isolate()), false, + "undefined", Oddball::kArgumentsMarker)); set_no_interceptor_result_sentinel(*factory->NewOddball( factory->no_interceptor_result_sentinel_map(), "no_interceptor_result_sentinel", handle(Smi::FromInt(-2), isolate()), - "undefined", Oddball::kOther)); + false, "undefined", Oddball::kOther)); set_termination_exception(*factory->NewOddball( factory->termination_exception_map(), "termination_exception", - handle(Smi::FromInt(-3), isolate()), "undefined", Oddball::kOther)); + handle(Smi::FromInt(-3), isolate()), false, "undefined", + Oddball::kOther)); set_exception(*factory->NewOddball(factory->exception_map(), "exception", - handle(Smi::FromInt(-5), isolate()), + handle(Smi::FromInt(-5), isolate()), false, "undefined", Oddball::kException)); for (unsigned i = 0; i < arraysize(constant_string_table); i++) { diff --git a/src/heap/heap.h b/src/heap/heap.h index 4c8ea48c0e..cf0590f535 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -652,7 +652,7 @@ class Heap { void RightTrimFixedArray(FixedArrayBase* obj, int elements_to_trim); // Converts the given boolean condition to JavaScript boolean value. - inline Object* ToBoolean(bool condition); + inline Oddball* ToBoolean(bool condition); // Check whether the heap is currently iterable. bool IsHeapIterable(); diff --git a/src/ic/ic.cc b/src/ic/ic.cc index c7ab8cec04..064c76b135 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -2720,7 +2720,7 @@ RUNTIME_FUNCTION(Runtime_Unreachable) { Handle ToBooleanIC::ToBoolean(Handle object) { - ToBooleanStub stub(isolate(), target()->extra_ic_state()); + ToBooleanICStub stub(isolate(), target()->extra_ic_state()); bool to_boolean_value = stub.UpdateStatus(object); Handle code = stub.GetCode(); set_target(*code); diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc index 580c0699ff..24f0e452bc 100644 --- a/src/interpreter/interpreter.cc +++ b/src/interpreter/interpreter.cc @@ -886,15 +886,29 @@ void Interpreter::DoDec(InterpreterAssembler* assembler) { // Perform logical-not on the accumulator, first casting the // accumulator to a boolean value if required. void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) { + Callable callable = CodeFactory::ToBoolean(isolate_); + Node* target = __ HeapConstant(callable.code()); Node* accumulator = __ GetAccumulator(); Node* context = __ GetContext(); - Node* result = - __ CallRuntime(Runtime::kInterpreterLogicalNot, context, accumulator); - __ SetAccumulator(result); - __ Dispatch(); + Node* to_boolean_value = + __ CallStub(callable.descriptor(), target, context, accumulator); + InterpreterAssembler::Label if_true(assembler), if_false(assembler); + Node* true_value = __ BooleanConstant(true); + Node* false_value = __ BooleanConstant(false); + Node* condition = __ WordEqual(to_boolean_value, true_value); + __ Branch(condition, &if_true, &if_false); + __ Bind(&if_true); + { + __ SetAccumulator(false_value); + __ Dispatch(); + } + __ Bind(&if_false); + { + __ SetAccumulator(true_value); + __ Dispatch(); + } } - // TypeOf // // Load the accumulator with the string representating type of the @@ -1363,10 +1377,12 @@ void Interpreter::DoJumpIfFalseConstantWide(InterpreterAssembler* assembler) { // Jump by number of bytes represented by an immediate operand if the object // referenced by the accumulator is true when the object is cast to boolean. void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) { + Callable callable = CodeFactory::ToBoolean(isolate_); + Node* target = __ HeapConstant(callable.code()); Node* accumulator = __ GetAccumulator(); Node* context = __ GetContext(); Node* to_boolean_value = - __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator); + __ CallStub(callable.descriptor(), target, context, accumulator); Node* relative_jump = __ BytecodeOperandImm(0); Node* true_value = __ BooleanConstant(true); __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); @@ -1380,10 +1396,12 @@ void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) { // to boolean. void Interpreter::DoJumpIfToBooleanTrueConstant( InterpreterAssembler* assembler) { + Callable callable = CodeFactory::ToBoolean(isolate_); + Node* target = __ HeapConstant(callable.code()); Node* accumulator = __ GetAccumulator(); Node* context = __ GetContext(); Node* to_boolean_value = - __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator); + __ CallStub(callable.descriptor(), target, context, accumulator); Node* index = __ BytecodeOperandIdx(0); Node* constant = __ LoadConstantPoolEntry(index); Node* relative_jump = __ SmiUntag(constant); @@ -1408,10 +1426,12 @@ void Interpreter::DoJumpIfToBooleanTrueConstantWide( // Jump by number of bytes represented by an immediate operand if the object // referenced by the accumulator is false when the object is cast to boolean. void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) { + Callable callable = CodeFactory::ToBoolean(isolate_); + Node* target = __ HeapConstant(callable.code()); Node* accumulator = __ GetAccumulator(); Node* context = __ GetContext(); Node* to_boolean_value = - __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator); + __ CallStub(callable.descriptor(), target, context, accumulator); Node* relative_jump = __ BytecodeOperandImm(0); Node* false_value = __ BooleanConstant(false); __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); @@ -1425,10 +1445,12 @@ void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) { // to boolean. void Interpreter::DoJumpIfToBooleanFalseConstant( InterpreterAssembler* assembler) { + Callable callable = CodeFactory::ToBoolean(isolate_); + Node* target = __ HeapConstant(callable.code()); Node* accumulator = __ GetAccumulator(); Node* context = __ GetContext(); Node* to_boolean_value = - __ CallRuntime(Runtime::kInterpreterToBoolean, context, accumulator); + __ CallStub(callable.descriptor(), target, context, accumulator); Node* index = __ BytecodeOperandIdx(0); Node* constant = __ LoadConstantPoolEntry(index); Node* relative_jump = __ SmiUntag(constant); diff --git a/src/objects-inl.h b/src/objects-inl.h index 86cd2d2a7c..ae5016e932 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1847,6 +1847,7 @@ InterceptorInfo* JSObject::GetIndexedInterceptor() { ACCESSORS(Oddball, to_string, String, kToStringOffset) ACCESSORS(Oddball, to_number, Object, kToNumberOffset) +ACCESSORS(Oddball, to_boolean, Oddball, kToBooleanOffset) ACCESSORS(Oddball, type_of, String, kTypeOfOffset) diff --git a/src/objects.cc b/src/objects.cc index d6c60f1845..7c5c92080a 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -13396,14 +13396,14 @@ Handle JSFunction::ToString(Handle function) { return builder.Finish().ToHandleChecked(); } - void Oddball::Initialize(Isolate* isolate, Handle oddball, const char* to_string, Handle to_number, - const char* type_of, byte kind) { + bool to_boolean, const char* type_of, byte kind) { Handle internalized_to_string = isolate->factory()->InternalizeUtf8String(to_string); Handle internalized_type_of = isolate->factory()->InternalizeUtf8String(type_of); + oddball->set_to_boolean(isolate->heap()->ToBoolean(to_boolean)); oddball->set_to_number(*to_number); oddball->set_to_string(*internalized_to_string); oddball->set_type_of(*internalized_type_of); diff --git a/src/objects.h b/src/objects.h index dd0ec9226b..42697930f0 100644 --- a/src/objects.h +++ b/src/objects.h @@ -9546,6 +9546,9 @@ class Oddball: public HeapObject { // [to_number]: Cached to_number computed at startup. DECL_ACCESSORS(to_number, Object) + // [to_number]: Cached to_boolean computed at startup. + DECL_ACCESSORS(to_boolean, Oddball) + // [typeof]: Cached type_of computed at startup. DECL_ACCESSORS(type_of, String) @@ -9563,12 +9566,13 @@ class Oddball: public HeapObject { // Initialize the fields. static void Initialize(Isolate* isolate, Handle oddball, const char* to_string, Handle to_number, - const char* type_of, byte kind); + bool to_boolean, const char* type_of, byte kind); // Layout description. static const int kToStringOffset = HeapObject::kHeaderSize; static const int kToNumberOffset = kToStringOffset + kPointerSize; - static const int kTypeOfOffset = kToNumberOffset + kPointerSize; + static const int kToBooleanOffset = kToNumberOffset + kPointerSize; + static const int kTypeOfOffset = kToBooleanOffset + kPointerSize; static const int kKindOffset = kTypeOfOffset + kPointerSize; static const int kSize = kKindOffset + kPointerSize; diff --git a/src/runtime/runtime-interpreter.cc b/src/runtime/runtime-interpreter.cc index f1525f1a88..9c53317b4a 100644 --- a/src/runtime/runtime-interpreter.cc +++ b/src/runtime/runtime-interpreter.cc @@ -16,22 +16,6 @@ namespace v8 { namespace internal { -RUNTIME_FUNCTION(Runtime_InterpreterToBoolean) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_CHECKED(Object, x, 0); - return isolate->heap()->ToBoolean(x->BooleanValue()); -} - - -RUNTIME_FUNCTION(Runtime_InterpreterLogicalNot) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_CHECKED(Object, x, 0); - return isolate->heap()->ToBoolean(!x->BooleanValue()); -} - - RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 1a4a4308b0..ce9a054aed 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -206,8 +206,6 @@ namespace internal { F(ForInStep, 1, 1) #define FOR_EACH_INTRINSIC_INTERPRETER(F) \ - F(InterpreterToBoolean, 1, 1) \ - F(InterpreterLogicalNot, 1, 1) \ F(InterpreterNewClosure, 2, 1) \ F(InterpreterTraceBytecodeEntry, 3, 1) \ F(InterpreterTraceBytecodeExit, 3, 1) \ diff --git a/src/type-info.h b/src/type-info.h index 13a7f88b66..c4b0928fc4 100644 --- a/src/type-info.h +++ b/src/type-info.h @@ -71,7 +71,7 @@ class TypeFeedbackOracle: public ZoneObject { Handle GetCallNewTarget(FeedbackVectorSlot slot); Handle GetCallNewAllocationSite(FeedbackVectorSlot slot); - // TODO(1571) We can't use ToBooleanStub::Types as the return value because + // TODO(1571) We can't use ToBooleanICStub::Types as the return value because // of various cycles in our headers. Death to tons of implementations in // headers!! :-P uint16_t ToBooleanTypes(TypeFeedbackId id); diff --git a/test/unittests/runtime/runtime-interpreter-unittest.cc b/test/unittests/runtime/runtime-interpreter-unittest.cc deleted file mode 100644 index c10ddcd319..0000000000 --- a/test/unittests/runtime/runtime-interpreter-unittest.cc +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015 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. - -#include "src/v8.h" - -#include "src/factory.h" -#include "src/heap/heap.h" -#include "src/heap/heap-inl.h" -#include "src/runtime/runtime.h" -#include "test/unittests/test-utils.h" - -namespace v8 { -namespace internal { -namespace interpreter { - -class RuntimeInterpreterTest : public TestWithIsolateAndZone { - public: - typedef Object* (*RuntimeMethod)(int, Object**, Isolate*); - - RuntimeInterpreterTest() {} - ~RuntimeInterpreterTest() override {} - - bool TestOperatorWithObjects(RuntimeMethod method, Handle lhs, - Handle rhs, bool expected); -}; - - -bool RuntimeInterpreterTest::TestOperatorWithObjects(RuntimeMethod method, - Handle lhs, - Handle rhs, - bool expected) { - Object* args_object[] = {*rhs, *lhs}; - Handle result = - handle(method(2, &args_object[1], isolate()), isolate()); - CHECK(result->IsTrue() || result->IsFalse()); - return result->IsTrue() == expected; -} - - -TEST_F(RuntimeInterpreterTest, ToBoolean) { - double quiet_nan = std::numeric_limits::quiet_NaN(); - std::pair, bool> cases[] = { - std::make_pair(isolate()->factory()->NewNumberFromInt(0), false), - std::make_pair(isolate()->factory()->NewNumberFromInt(1), true), - std::make_pair(isolate()->factory()->NewNumberFromInt(100), true), - std::make_pair(isolate()->factory()->NewNumberFromInt(-1), true), - std::make_pair(isolate()->factory()->NewNumber(7.7), true), - std::make_pair(isolate()->factory()->NewNumber(0.00001), true), - std::make_pair(isolate()->factory()->NewNumber(quiet_nan), false), - std::make_pair(isolate()->factory()->NewHeapNumber(0.0), false), - std::make_pair(isolate()->factory()->undefined_value(), false), - std::make_pair(isolate()->factory()->null_value(), false), - std::make_pair(isolate()->factory()->true_value(), true), - std::make_pair(isolate()->factory()->false_value(), false), - std::make_pair(isolate()->factory()->NewStringFromStaticChars(""), false), - std::make_pair(isolate()->factory()->NewStringFromStaticChars("_"), true), - }; - - for (size_t i = 0; i < arraysize(cases); i++) { - auto& value_expected_tuple = cases[i]; - Object* args_object[] = {*value_expected_tuple.first}; - Handle result = handle( - Runtime_InterpreterToBoolean(1, &args_object[0], isolate()), isolate()); - CHECK(result->IsBoolean()); - CHECK_EQ(result->IsTrue(), value_expected_tuple.second); - } -} - - -} // namespace interpreter -} // namespace internal -} // namespace v8 diff --git a/test/unittests/unittests.gyp b/test/unittests/unittests.gyp index fe9cd28a8a..f4a9e88c8d 100644 --- a/test/unittests/unittests.gyp +++ b/test/unittests/unittests.gyp @@ -115,7 +115,6 @@ 'heap/remembered-set-unittest.cc', 'locked-queue-unittest.cc', 'run-all-unittests.cc', - 'runtime/runtime-interpreter-unittest.cc', 'test-utils.h', 'test-utils.cc', 'wasm/ast-decoder-unittest.cc',