diff options
Diffstat (limited to 'chromium/v8/src/ia32/lithium-ia32.h')
-rw-r--r-- | chromium/v8/src/ia32/lithium-ia32.h | 731 |
1 files changed, 331 insertions, 400 deletions
diff --git a/chromium/v8/src/ia32/lithium-ia32.h b/chromium/v8/src/ia32/lithium-ia32.h index c865d8d0e9a..e12ca5e9bda 100644 --- a/chromium/v8/src/ia32/lithium-ia32.h +++ b/chromium/v8/src/ia32/lithium-ia32.h @@ -1,38 +1,15 @@ // Copyright 2012 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. #ifndef V8_IA32_LITHIUM_IA32_H_ #define V8_IA32_LITHIUM_IA32_H_ -#include "hydrogen.h" -#include "lithium-allocator.h" -#include "lithium.h" -#include "safepoint-table.h" -#include "utils.h" +#include "src/hydrogen.h" +#include "src/lithium-allocator.h" +#include "src/lithium.h" +#include "src/safepoint-table.h" +#include "src/utils.h" namespace v8 { namespace internal { @@ -43,6 +20,7 @@ class LCodeGen; #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ V(AccessArgumentsAt) \ V(AddI) \ + V(AllocateBlockContext) \ V(Allocate) \ V(ApplyArguments) \ V(ArgumentsElements) \ @@ -52,12 +30,9 @@ class LCodeGen; V(BitI) \ V(BoundsCheck) \ V(Branch) \ - V(CallConstantFunction) \ + V(CallJSFunction) \ + V(CallWithDescriptor) \ V(CallFunction) \ - V(CallGlobal) \ - V(CallKeyed) \ - V(CallKnownGlobal) \ - V(CallNamed) \ V(CallNew) \ V(CallNewArray) \ V(CallRuntime) \ @@ -71,9 +46,7 @@ class LCodeGen; V(ClampDToUint8) \ V(ClampIToUint8) \ V(ClampTToUint8) \ - V(ClampTToUint8NoSSE2) \ V(ClassOfTestAndBranch) \ - V(ClobberDoubles) \ V(CompareMinusZeroAndBranch) \ V(CompareNumericAndBranch) \ V(CmpObjectEqAndBranch) \ @@ -85,24 +58,28 @@ class LCodeGen; V(ConstantI) \ V(ConstantS) \ V(ConstantT) \ + V(ConstructDouble) \ V(Context) \ V(DateField) \ V(DebugBreak) \ V(DeclareGlobals) \ V(Deoptimize) \ + V(DivByConstI) \ + V(DivByPowerOf2I) \ V(DivI) \ + V(DoubleBits) \ V(DoubleToI) \ V(DoubleToSmi) \ V(Drop) \ V(Dummy) \ V(DummyUse) \ - V(ElementsKind) \ + V(FlooringDivByConstI) \ + V(FlooringDivByPowerOf2I) \ + V(FlooringDivI) \ V(ForInCacheArray) \ V(ForInPrepareMap) \ V(FunctionLiteral) \ V(GetCachedArrayIndex) \ - V(GlobalObject) \ - V(GlobalReceiver) \ V(Goto) \ V(HasCachedArrayIndexAndBranch) \ V(HasInstanceTypeAndBranch) \ @@ -111,7 +88,6 @@ class LCodeGen; V(InstanceOfKnownGlobal) \ V(InstructionGap) \ V(Integer32ToDouble) \ - V(Integer32ToSmi) \ V(InvokeFunction) \ V(IsConstructCallAndBranch) \ V(IsObjectAndBranch) \ @@ -121,7 +97,6 @@ class LCodeGen; V(Label) \ V(LazyBailout) \ V(LoadContextSlot) \ - V(LoadExternalArrayPointer) \ V(LoadFieldByIndex) \ V(LoadFunctionPrototype) \ V(LoadGlobalCell) \ @@ -133,17 +108,16 @@ class LCodeGen; V(LoadRoot) \ V(MapEnumLength) \ V(MathAbs) \ - V(MathCos) \ + V(MathClz32) \ V(MathExp) \ V(MathFloor) \ - V(MathFloorOfDiv) \ V(MathLog) \ V(MathMinMax) \ V(MathPowHalf) \ V(MathRound) \ - V(MathSin) \ V(MathSqrt) \ - V(MathTan) \ + V(ModByConstI) \ + V(ModByPowerOf2I) \ V(ModI) \ V(MulI) \ V(NumberTagD) \ @@ -151,7 +125,6 @@ class LCodeGen; V(NumberTagU) \ V(NumberUntagD) \ V(OsrEntry) \ - V(OuterContext) \ V(Parameter) \ V(Power) \ V(PushArgument) \ @@ -165,8 +138,8 @@ class LCodeGen; V(StackCheck) \ V(StoreCodeEntry) \ V(StoreContextSlot) \ + V(StoreFrameContext) \ V(StoreGlobalCell) \ - V(StoreGlobalGeneric) \ V(StoreKeyed) \ V(StoreKeyedGeneric) \ V(StoreNamedField) \ @@ -178,16 +151,13 @@ class LCodeGen; V(SubI) \ V(TaggedToI) \ V(ThisFunction) \ - V(Throw) \ V(ToFastProperties) \ V(TransitionElementsKind) \ V(TrapAllocationMemento) \ V(Typeof) \ V(TypeofIsAndBranch) \ V(Uint32ToDouble) \ - V(Uint32ToSmi) \ V(UnknownOSRValue) \ - V(ValueOf) \ V(WrapReceiver) @@ -268,11 +238,8 @@ class LInstruction : public ZoneObject { // Interface to the register allocator and iterators. bool ClobbersTemps() const { return IsCall(); } bool ClobbersRegisters() const { return IsCall(); } - virtual bool ClobbersDoubleRegisters() const { - return IsCall() || - // We only have rudimentary X87Stack tracking, thus in general - // cannot handle phi-nodes. - (!CpuFeatures::IsSafeForSnapshot(SSE2) && IsControl()); + virtual bool ClobbersDoubleRegisters(Isolate* isolate) const { + return IsCall(); } virtual bool HasResult() const = 0; @@ -280,7 +247,6 @@ class LInstruction : public ZoneObject { bool HasDoubleRegisterResult(); bool HasDoubleRegisterInput(); - bool IsDoubleInput(X87Register reg, LCodeGen* cgen); LOperand* FirstInput() { return InputAt(0); } LOperand* Output() { return HasResult() ? result() : NULL; } @@ -311,10 +277,8 @@ class LInstruction : public ZoneObject { // R = number of result operands (0 or 1). -// I = number of input operands. -// T = number of temporary operands. -template<int R, int I, int T> -class LTemplateInstruction : public LInstruction { +template<int R> +class LTemplateResultInstruction : public LInstruction { public: // Allow 0 or 1 output operands. STATIC_ASSERT(R == 0 || R == 1); @@ -326,6 +290,15 @@ class LTemplateInstruction : public LInstruction { protected: EmbeddedContainer<LOperand*, R> results_; +}; + + +// R = number of result operands (0 or 1). +// I = number of input operands. +// T = number of temporary operands. +template<int R, int I, int T> +class LTemplateInstruction : public LTemplateResultInstruction<R> { + protected: EmbeddedContainer<LOperand*, I> inputs_; EmbeddedContainer<LOperand*, T> temps_; @@ -398,16 +371,6 @@ class LInstructionGap V8_FINAL : public LGap { }; -class LClobberDoubles V8_FINAL : public LTemplateInstruction<0, 0, 0> { - public: - LClobberDoubles() { ASSERT(!CpuFeatures::IsSafeForSnapshot(SSE2)); } - - virtual bool ClobbersDoubleRegisters() const { return true; } - - DECLARE_CONCRETE_INSTRUCTION(ClobberDoubles, "clobber-d") -}; - - class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> { public: explicit LGoto(HBasicBlock* block) : block_(block) { } @@ -418,7 +381,9 @@ class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> { virtual bool IsControl() const V8_OVERRIDE { return true; } int block_id() const { return block_->block_id(); } - virtual bool ClobbersDoubleRegisters() const { return false; } + virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_OVERRIDE { + return false; + } bool jumps_to_join() const { return block_->predecessors()->length() > 1; } @@ -451,6 +416,7 @@ class LDummyUse V8_FINAL : public LTemplateInstruction<1, 1, 0> { class LDeoptimize V8_FINAL : public LTemplateInstruction<0, 0, 0> { public: + virtual bool IsControl() const V8_OVERRIDE { return true; } DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize") DECLARE_HYDROGEN_ACCESSOR(Deoptimize) }; @@ -501,10 +467,6 @@ class LCallStub V8_FINAL : public LTemplateInstruction<1, 1, 0> { DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub") DECLARE_HYDROGEN_ACCESSOR(CallStub) - - TranscendentalCache::Type transcendental_type() { - return hydrogen()->transcendental_type(); - } }; @@ -576,6 +538,7 @@ class LWrapReceiver V8_FINAL : public LTemplateInstruction<1, 2, 1> { LOperand* temp() { return temps_[0]; } DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver") + DECLARE_HYDROGEN_ACCESSOR(WrapReceiver) }; @@ -643,6 +606,49 @@ class LDebugBreak V8_FINAL : public LTemplateInstruction<0, 0, 0> { }; +class LModByPowerOf2I V8_FINAL : public LTemplateInstruction<1, 1, 0> { + public: + LModByPowerOf2I(LOperand* dividend, int32_t divisor) { + inputs_[0] = dividend; + divisor_ = divisor; + } + + LOperand* dividend() { return inputs_[0]; } + int32_t divisor() const { return divisor_; } + + DECLARE_CONCRETE_INSTRUCTION(ModByPowerOf2I, "mod-by-power-of-2-i") + DECLARE_HYDROGEN_ACCESSOR(Mod) + + private: + int32_t divisor_; +}; + + +class LModByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> { + public: + LModByConstI(LOperand* dividend, + int32_t divisor, + LOperand* temp1, + LOperand* temp2) { + inputs_[0] = dividend; + divisor_ = divisor; + temps_[0] = temp1; + temps_[1] = temp2; + } + + LOperand* dividend() { return inputs_[0]; } + int32_t divisor() const { return divisor_; } + LOperand* temp1() { return temps_[0]; } + LOperand* temp2() { return temps_[1]; } + + DECLARE_CONCRETE_INSTRUCTION(ModByConstI, "mod-by-const-i") + DECLARE_HYDROGEN_ACCESSOR(Mod) + + private: + int32_t divisor_; +}; + + class LModI V8_FINAL : public LTemplateInstruction<1, 2, 1> { public: LModI(LOperand* left, LOperand* right, LOperand* temp) { @@ -660,39 +666,126 @@ class LModI V8_FINAL : public LTemplateInstruction<1, 2, 1> { }; +class LDivByPowerOf2I V8_FINAL : public LTemplateInstruction<1, 1, 0> { + public: + LDivByPowerOf2I(LOperand* dividend, int32_t divisor) { + inputs_[0] = dividend; + divisor_ = divisor; + } + + LOperand* dividend() { return inputs_[0]; } + int32_t divisor() const { return divisor_; } + + DECLARE_CONCRETE_INSTRUCTION(DivByPowerOf2I, "div-by-power-of-2-i") + DECLARE_HYDROGEN_ACCESSOR(Div) + + private: + int32_t divisor_; +}; + + +class LDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> { + public: + LDivByConstI(LOperand* dividend, + int32_t divisor, + LOperand* temp1, + LOperand* temp2) { + inputs_[0] = dividend; + divisor_ = divisor; + temps_[0] = temp1; + temps_[1] = temp2; + } + + LOperand* dividend() { return inputs_[0]; } + int32_t divisor() const { return divisor_; } + LOperand* temp1() { return temps_[0]; } + LOperand* temp2() { return temps_[1]; } + + DECLARE_CONCRETE_INSTRUCTION(DivByConstI, "div-by-const-i") + DECLARE_HYDROGEN_ACCESSOR(Div) + + private: + int32_t divisor_; +}; + + class LDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> { public: - LDivI(LOperand* left, LOperand* right, LOperand* temp) { - inputs_[0] = left; - inputs_[1] = right; + LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) { + inputs_[0] = dividend; + inputs_[1] = divisor; temps_[0] = temp; } - LOperand* left() { return inputs_[0]; } - LOperand* right() { return inputs_[1]; } - - bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); } + LOperand* dividend() { return inputs_[0]; } + LOperand* divisor() { return inputs_[1]; } + LOperand* temp() { return temps_[0]; } DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i") - DECLARE_HYDROGEN_ACCESSOR(Div) + DECLARE_HYDROGEN_ACCESSOR(BinaryOperation) }; -class LMathFloorOfDiv V8_FINAL : public LTemplateInstruction<1, 2, 1> { +class LFlooringDivByPowerOf2I V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: - LMathFloorOfDiv(LOperand* left, - LOperand* right, - LOperand* temp = NULL) { - inputs_[0] = left; - inputs_[1] = right; + LFlooringDivByPowerOf2I(LOperand* dividend, int32_t divisor) { + inputs_[0] = dividend; + divisor_ = divisor; + } + + LOperand* dividend() { return inputs_[0]; } + int32_t divisor() const { return divisor_; } + + DECLARE_CONCRETE_INSTRUCTION(FlooringDivByPowerOf2I, + "flooring-div-by-power-of-2-i") + DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) + + private: + int32_t divisor_; +}; + + +class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 3> { + public: + LFlooringDivByConstI(LOperand* dividend, + int32_t divisor, + LOperand* temp1, + LOperand* temp2, + LOperand* temp3) { + inputs_[0] = dividend; + divisor_ = divisor; + temps_[0] = temp1; + temps_[1] = temp2; + temps_[2] = temp3; + } + + LOperand* dividend() { return inputs_[0]; } + int32_t divisor() const { return divisor_; } + LOperand* temp1() { return temps_[0]; } + LOperand* temp2() { return temps_[1]; } + LOperand* temp3() { return temps_[2]; } + + DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i") + DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) + + private: + int32_t divisor_; +}; + + +class LFlooringDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> { + public: + LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) { + inputs_[0] = dividend; + inputs_[1] = divisor; temps_[0] = temp; } - LOperand* left() { return inputs_[0]; } - LOperand* right() { return inputs_[1]; } + LOperand* dividend() { return inputs_[0]; } + LOperand* divisor() { return inputs_[1]; } LOperand* temp() { return temps_[0]; } - DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv, "math-floor-of-div") + DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i") DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv) }; @@ -792,39 +885,15 @@ class LMathLog V8_FINAL : public LTemplateInstruction<1, 1, 0> { }; -class LMathSin V8_FINAL : public LTemplateInstruction<1, 1, 0> { - public: - explicit LMathSin(LOperand* value) { - inputs_[0] = value; - } - - LOperand* value() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin") -}; - - -class LMathCos V8_FINAL : public LTemplateInstruction<1, 1, 0> { - public: - explicit LMathCos(LOperand* value) { - inputs_[0] = value; - } - - LOperand* value() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos") -}; - - -class LMathTan V8_FINAL : public LTemplateInstruction<1, 1, 0> { +class LMathClz32 V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: - explicit LMathTan(LOperand* value) { + explicit LMathClz32(LOperand* value) { inputs_[0] = value; } LOperand* value() { return inputs_[0]; } - DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan") + DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32") }; @@ -1312,34 +1381,6 @@ class LMapEnumLength V8_FINAL : public LTemplateInstruction<1, 1, 0> { }; -class LElementsKind V8_FINAL : public LTemplateInstruction<1, 1, 0> { - public: - explicit LElementsKind(LOperand* value) { - inputs_[0] = value; - } - - LOperand* value() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(ElementsKind, "elements-kind") - DECLARE_HYDROGEN_ACCESSOR(ElementsKind) -}; - - -class LValueOf V8_FINAL : public LTemplateInstruction<1, 1, 1> { - public: - LValueOf(LOperand* value, LOperand* temp) { - inputs_[0] = value; - temps_[0] = temp; - } - - LOperand* value() { return inputs_[0]; } - LOperand* temp() { return temps_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of") - DECLARE_HYDROGEN_ACCESSOR(ValueOf) -}; - - class LDateField V8_FINAL : public LTemplateInstruction<1, 1, 1> { public: LDateField(LOperand* date, LOperand* temp, Smi* index) @@ -1397,20 +1438,6 @@ class LSeqStringSetChar V8_FINAL : public LTemplateInstruction<1, 4, 0> { }; -class LThrow V8_FINAL : public LTemplateInstruction<0, 2, 0> { - public: - LThrow(LOperand* context, LOperand* value) { - inputs_[0] = context; - inputs_[1] = value; - } - - LOperand* context() { return inputs_[0]; } - LOperand* value() { return inputs_[1]; } - - DECLARE_CONCRETE_INSTRUCTION(Throw, "throw") -}; - - class LAddI V8_FINAL : public LTemplateInstruction<1, 2, 0> { public: LAddI(LOperand* left, LOperand* right) { @@ -1592,20 +1619,6 @@ class LLoadRoot V8_FINAL : public LTemplateInstruction<1, 0, 0> { }; -class LLoadExternalArrayPointer V8_FINAL - : public LTemplateInstruction<1, 1, 0> { - public: - explicit LLoadExternalArrayPointer(LOperand* object) { - inputs_[0] = object; - } - - LOperand* object() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer, - "load-external-array-pointer") -}; - - class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> { public: LLoadKeyed(LOperand* elements, LOperand* key) { @@ -1620,12 +1633,18 @@ class LLoadKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> { bool is_external() const { return hydrogen()->is_external(); } + bool is_fixed_typed_array() const { + return hydrogen()->is_fixed_typed_array(); + } + bool is_typed_elements() const { + return is_external() || is_fixed_typed_array(); + } DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed") DECLARE_HYDROGEN_ACCESSOR(LoadKeyed) virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - uint32_t additional_index() const { return hydrogen()->index_offset(); } + uint32_t base_offset() const { return hydrogen()->base_offset(); } bool key_is_smi() { return hydrogen()->key()->representation().IsTagged(); } @@ -1639,9 +1658,12 @@ inline static bool ExternalArrayOpRequiresTemp( // an index cannot fold the scale operation into a load and need an extra // temp register to do the work. return key_representation.IsSmi() && - (elements_kind == EXTERNAL_BYTE_ELEMENTS || - elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS || - elements_kind == EXTERNAL_PIXEL_ELEMENTS); + (elements_kind == EXTERNAL_INT8_ELEMENTS || + elements_kind == EXTERNAL_UINT8_ELEMENTS || + elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || + elements_kind == UINT8_ELEMENTS || + elements_kind == INT8_ELEMENTS || + elements_kind == UINT8_CLAMPED_ELEMENTS); } @@ -1699,28 +1721,6 @@ class LStoreGlobalCell V8_FINAL : public LTemplateInstruction<0, 1, 0> { }; -class LStoreGlobalGeneric V8_FINAL : public LTemplateInstruction<0, 3, 0> { - public: - LStoreGlobalGeneric(LOperand* context, - LOperand* global_object, - LOperand* value) { - inputs_[0] = context; - inputs_[1] = global_object; - inputs_[2] = value; - } - - LOperand* context() { return inputs_[0]; } - LOperand* global_object() { return inputs_[1]; } - LOperand* value() { return inputs_[2]; } - - DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric, "store-global-generic") - DECLARE_HYDROGEN_ACCESSOR(StoreGlobalGeneric) - - Handle<Object> name() const { return hydrogen()->name(); } - StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); } -}; - - class LLoadContextSlot V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: explicit LLoadContextSlot(LOperand* context) { @@ -1784,15 +1784,15 @@ class LDrop V8_FINAL : public LTemplateInstruction<0, 0, 0> { }; -class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> { +class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 2, 0> { public: LStoreCodeEntry(LOperand* function, LOperand* code_object) { inputs_[0] = function; - temps_[0] = code_object; + inputs_[1] = code_object; } LOperand* function() { return inputs_[0]; } - LOperand* code_object() { return temps_[0]; } + LOperand* code_object() { return inputs_[1]; } virtual void PrintDataTo(StringStream* stream); @@ -1831,18 +1831,6 @@ class LContext V8_FINAL : public LTemplateInstruction<1, 0, 0> { }; -class LOuterContext V8_FINAL : public LTemplateInstruction<1, 1, 0> { - public: - explicit LOuterContext(LOperand* context) { - inputs_[0] = context; - } - - LOperand* context() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer-context") -}; - - class LDeclareGlobals V8_FINAL : public LTemplateInstruction<0, 1, 0> { public: explicit LDeclareGlobals(LOperand* context) { @@ -1856,94 +1844,69 @@ class LDeclareGlobals V8_FINAL : public LTemplateInstruction<0, 1, 0> { }; -class LGlobalObject V8_FINAL : public LTemplateInstruction<1, 1, 0> { +class LCallJSFunction V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: - explicit LGlobalObject(LOperand* context) { - inputs_[0] = context; - } - - LOperand* context() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object") -}; - - -class LGlobalReceiver V8_FINAL : public LTemplateInstruction<1, 1, 0> { - public: - explicit LGlobalReceiver(LOperand* global_object) { - inputs_[0] = global_object; + explicit LCallJSFunction(LOperand* function) { + inputs_[0] = function; } - LOperand* global() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global-receiver") -}; - + LOperand* function() { return inputs_[0]; } -class LCallConstantFunction V8_FINAL : public LTemplateInstruction<1, 0, 0> { - public: - DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call-constant-function") - DECLARE_HYDROGEN_ACCESSOR(CallConstantFunction) + DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function") + DECLARE_HYDROGEN_ACCESSOR(CallJSFunction) virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - Handle<JSFunction> function() { return hydrogen()->function(); } int arity() const { return hydrogen()->argument_count() - 1; } }; -class LInvokeFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> { +class LCallWithDescriptor V8_FINAL : public LTemplateResultInstruction<1> { public: - LInvokeFunction(LOperand* context, LOperand* function) { - inputs_[0] = context; - inputs_[1] = function; + LCallWithDescriptor(const CallInterfaceDescriptor* descriptor, + const ZoneList<LOperand*>& operands, + Zone* zone) + : inputs_(descriptor->environment_length() + 1, zone) { + ASSERT(descriptor->environment_length() + 1 == operands.length()); + inputs_.AddAll(operands, zone); } - LOperand* context() { return inputs_[0]; } - LOperand* function() { return inputs_[1]; } + LOperand* target() const { return inputs_[0]; } - DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function") - DECLARE_HYDROGEN_ACCESSOR(InvokeFunction) + private: + DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor") + DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor) virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; int arity() const { return hydrogen()->argument_count() - 1; } -}; + ZoneList<LOperand*> inputs_; -class LCallKeyed V8_FINAL : public LTemplateInstruction<1, 2, 0> { - public: - LCallKeyed(LOperand* context, LOperand* key) { - inputs_[0] = context; - inputs_[1] = key; - } - - LOperand* context() { return inputs_[0]; } - LOperand* key() { return inputs_[1]; } - - DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed") - DECLARE_HYDROGEN_ACCESSOR(CallKeyed) - - virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; + // Iterator support. + virtual int InputCount() V8_FINAL V8_OVERRIDE { return inputs_.length(); } + virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; } - int arity() const { return hydrogen()->argument_count() - 1; } + virtual int TempCount() V8_FINAL V8_OVERRIDE { return 0; } + virtual LOperand* TempAt(int i) V8_FINAL V8_OVERRIDE { return NULL; } }; -class LCallNamed V8_FINAL : public LTemplateInstruction<1, 1, 0> { +class LInvokeFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> { public: - explicit LCallNamed(LOperand* context) { + LInvokeFunction(LOperand* context, LOperand* function) { inputs_[0] = context; + inputs_[1] = function; } LOperand* context() { return inputs_[0]; } + LOperand* function() { return inputs_[1]; } - DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call-named") - DECLARE_HYDROGEN_ACCESSOR(CallNamed) + DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function") + DECLARE_HYDROGEN_ACCESSOR(InvokeFunction) virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - Handle<String> name() const { return hydrogen()->name(); } int arity() const { return hydrogen()->argument_count() - 1; } }; @@ -1965,35 +1928,6 @@ class LCallFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> { }; -class LCallGlobal V8_FINAL : public LTemplateInstruction<1, 1, 0> { - public: - explicit LCallGlobal(LOperand* context) { - inputs_[0] = context; - } - - LOperand* context() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global") - DECLARE_HYDROGEN_ACCESSOR(CallGlobal) - - virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - - Handle<String> name() const {return hydrogen()->name(); } - int arity() const { return hydrogen()->argument_count() - 1; } -}; - - -class LCallKnownGlobal V8_FINAL : public LTemplateInstruction<1, 0, 0> { - public: - DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call-known-global") - DECLARE_HYDROGEN_ACCESSOR(CallKnownGlobal) - - virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - - int arity() const { return hydrogen()->argument_count() - 1; } -}; - - class LCallNew V8_FINAL : public LTemplateInstruction<1, 2, 0> { public: LCallNew(LOperand* context, LOperand* constructor) { @@ -2043,7 +1977,7 @@ class LCallRuntime V8_FINAL : public LTemplateInstruction<1, 1, 0> { DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime") DECLARE_HYDROGEN_ACCESSOR(CallRuntime) - virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE { + virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_OVERRIDE { return save_doubles() == kDontSaveFPRegs; } @@ -2065,22 +1999,21 @@ class LInteger32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> { }; -class LInteger32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> { +class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: - explicit LInteger32ToSmi(LOperand* value) { + explicit LUint32ToDouble(LOperand* value) { inputs_[0] = value; } LOperand* value() { return inputs_[0]; } - DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi") - DECLARE_HYDROGEN_ACCESSOR(Change) + DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double") }; -class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 1> { +class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 1> { public: - explicit LUint32ToDouble(LOperand* value, LOperand* temp) { + LNumberTagI(LOperand* value, LOperand* temp) { inputs_[0] = value; temps_[0] = temp; } @@ -2088,31 +2021,6 @@ class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 1> { LOperand* value() { return inputs_[0]; } LOperand* temp() { return temps_[0]; } - DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double") -}; - - -class LUint32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> { - public: - explicit LUint32ToSmi(LOperand* value) { - inputs_[0] = value; - } - - LOperand* value() { return inputs_[0]; } - - DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi") - DECLARE_HYDROGEN_ACCESSOR(Change) -}; - - -class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 0> { - public: - explicit LNumberTagI(LOperand* value) { - inputs_[0] = value; - } - - LOperand* value() { return inputs_[0]; } - DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i") }; @@ -2204,6 +2112,7 @@ class LSmiTag V8_FINAL : public LTemplateInstruction<1, 1, 0> { LOperand* value() { return inputs_[0]; } DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag") + DECLARE_HYDROGEN_ACCESSOR(Change) }; @@ -2261,11 +2170,6 @@ class LStoreNamedField V8_FINAL : public LTemplateInstruction<0, 2, 2> { DECLARE_HYDROGEN_ACCESSOR(StoreNamedField) virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - - Handle<Map> transition() const { return hydrogen()->transition_map(); } - Representation representation() const { - return hydrogen()->field_representation(); - } }; @@ -2286,7 +2190,7 @@ class LStoreNamedGeneric V8_FINAL : public LTemplateInstruction<0, 3, 0> { virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; Handle<Object> name() const { return hydrogen()->name(); } - StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); } + StrictMode strict_mode() { return hydrogen()->strict_mode(); } }; @@ -2299,6 +2203,12 @@ class LStoreKeyed V8_FINAL : public LTemplateInstruction<0, 3, 0> { } bool is_external() const { return hydrogen()->is_external(); } + bool is_fixed_typed_array() const { + return hydrogen()->is_fixed_typed_array(); + } + bool is_typed_elements() const { + return is_external() || is_fixed_typed_array(); + } LOperand* elements() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } @@ -2310,7 +2220,7 @@ class LStoreKeyed V8_FINAL : public LTemplateInstruction<0, 3, 0> { DECLARE_HYDROGEN_ACCESSOR(StoreKeyed) virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - uint32_t additional_index() const { return hydrogen()->index_offset(); } + uint32_t base_offset() const { return hydrogen()->base_offset(); } bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } }; @@ -2337,7 +2247,7 @@ class LStoreKeyedGeneric V8_FINAL : public LTemplateInstruction<0, 4, 0> { virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; - StrictModeFlag strict_mode_flag() { return hydrogen()->strict_mode_flag(); } + StrictMode strict_mode() { return hydrogen()->strict_mode(); } }; @@ -2468,7 +2378,7 @@ class LCheckInstanceType V8_FINAL : public LTemplateInstruction<0, 1, 1> { class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 0> { public: - explicit LCheckMaps(LOperand* value) { + explicit LCheckMaps(LOperand* value = NULL) { inputs_[0] = value; } @@ -2529,40 +2439,43 @@ class LClampTToUint8 V8_FINAL : public LTemplateInstruction<1, 1, 1> { }; -// Truncating conversion from a tagged value to an int32. -class LClampTToUint8NoSSE2 V8_FINAL : public LTemplateInstruction<1, 1, 3> { +class LCheckNonSmi V8_FINAL : public LTemplateInstruction<0, 1, 0> { public: - LClampTToUint8NoSSE2(LOperand* unclamped, - LOperand* temp1, - LOperand* temp2, - LOperand* temp3) { - inputs_[0] = unclamped; - temps_[0] = temp1; - temps_[1] = temp2; - temps_[2] = temp3; + explicit LCheckNonSmi(LOperand* value) { + inputs_[0] = value; } - LOperand* unclamped() { return inputs_[0]; } - LOperand* scratch() { return temps_[0]; } - LOperand* scratch2() { return temps_[1]; } - LOperand* scratch3() { return temps_[2]; } + LOperand* value() { return inputs_[0]; } - DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8NoSSE2, - "clamp-t-to-uint8-nosse2") - DECLARE_HYDROGEN_ACCESSOR(UnaryOperation) + DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi") + DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject) }; -class LCheckNonSmi V8_FINAL : public LTemplateInstruction<0, 1, 0> { +class LDoubleBits V8_FINAL : public LTemplateInstruction<1, 1, 0> { public: - explicit LCheckNonSmi(LOperand* value) { + explicit LDoubleBits(LOperand* value) { inputs_[0] = value; } LOperand* value() { return inputs_[0]; } - DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi") - DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject) + DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits") + DECLARE_HYDROGEN_ACCESSOR(DoubleBits) +}; + + +class LConstructDouble V8_FINAL : public LTemplateInstruction<1, 2, 0> { + public: + LConstructDouble(LOperand* hi, LOperand* lo) { + inputs_[0] = hi; + inputs_[1] = lo; + } + + LOperand* hi() { return inputs_[0]; } + LOperand* lo() { return inputs_[1]; } + + DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double") }; @@ -2738,6 +2651,35 @@ class LLoadFieldByIndex V8_FINAL : public LTemplateInstruction<1, 2, 0> { }; +class LStoreFrameContext: public LTemplateInstruction<0, 1, 0> { + public: + explicit LStoreFrameContext(LOperand* context) { + inputs_[0] = context; + } + + LOperand* context() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(StoreFrameContext, "store-frame-context") +}; + + +class LAllocateBlockContext: public LTemplateInstruction<1, 2, 0> { + public: + LAllocateBlockContext(LOperand* context, LOperand* function) { + inputs_[0] = context; + inputs_[1] = function; + } + + LOperand* context() { return inputs_[0]; } + LOperand* function() { return inputs_[1]; } + + Handle<ScopeInfo> scope_info() { return hydrogen()->scope_info(); } + + DECLARE_CONCRETE_INSTRUCTION(AllocateBlockContext, "allocate-block-context") + DECLARE_HYDROGEN_ACCESSOR(AllocateBlockContext) +}; + + class LChunkBuilder; class LPlatformChunk V8_FINAL : public LChunk { public: @@ -2755,42 +2697,46 @@ class LPlatformChunk V8_FINAL : public LChunk { }; -class LChunkBuilder V8_FINAL BASE_EMBEDDED { +class LChunkBuilder V8_FINAL : public LChunkBuilderBase { public: LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator) - : chunk_(NULL), + : LChunkBuilderBase(graph->zone()), + chunk_(NULL), info_(info), graph_(graph), - zone_(graph->zone()), status_(UNUSED), current_instruction_(NULL), current_block_(NULL), next_block_(NULL), - argument_count_(0), allocator_(allocator) { } + Isolate* isolate() const { return graph_->isolate(); } + // Build the sequence for the graph. LPlatformChunk* Build(); - LInstruction* CheckElideControlInstruction(HControlInstruction* instr); - // Declare methods that deal with the individual node types. #define DECLARE_DO(type) LInstruction* Do##type(H##type* node); HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) #undef DECLARE_DO - static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val); - LInstruction* DoMathFloor(HUnaryMathOperation* instr); LInstruction* DoMathRound(HUnaryMathOperation* instr); LInstruction* DoMathAbs(HUnaryMathOperation* instr); LInstruction* DoMathLog(HUnaryMathOperation* instr); - LInstruction* DoMathSin(HUnaryMathOperation* instr); - LInstruction* DoMathCos(HUnaryMathOperation* instr); - LInstruction* DoMathTan(HUnaryMathOperation* instr); LInstruction* DoMathExp(HUnaryMathOperation* instr); LInstruction* DoMathSqrt(HUnaryMathOperation* instr); LInstruction* DoMathPowHalf(HUnaryMathOperation* instr); + LInstruction* DoMathClz32(HUnaryMathOperation* instr); + LInstruction* DoDivByPowerOf2I(HDiv* instr); + LInstruction* DoDivByConstI(HDiv* instr); + LInstruction* DoDivI(HDiv* instr); + LInstruction* DoModByPowerOf2I(HMod* instr); + LInstruction* DoModByConstI(HMod* instr); + LInstruction* DoModI(HMod* instr); + LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr); + LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr); + LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr); private: enum Status { @@ -2803,7 +2749,6 @@ class LChunkBuilder V8_FINAL BASE_EMBEDDED { LPlatformChunk* chunk() const { return chunk_; } CompilationInfo* info() const { return info_; } HGraph* graph() const { return graph_; } - Zone* zone() const { return zone_; } bool is_unused() const { return status_ == UNUSED; } bool is_building() const { return status_ == BUILDING; } @@ -2815,7 +2760,6 @@ class LChunkBuilder V8_FINAL BASE_EMBEDDED { // Methods for getting operands for Use / Define / Temp. LUnallocated* ToUnallocated(Register reg); LUnallocated* ToUnallocated(XMMRegister reg); - LUnallocated* ToUnallocated(X87Register reg); // Methods for setting up define-use relationships. MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand); @@ -2858,7 +2802,7 @@ class LChunkBuilder V8_FINAL BASE_EMBEDDED { // An input operand in register, stack slot or a constant operand. // Will not be moved to a register even if one is freely available. - MUST_USE_RESULT LOperand* UseAny(HValue* value); + virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) V8_OVERRIDE; // Temporary operand that must be in a register. MUST_USE_RESULT LUnallocated* TempRegister(); @@ -2867,24 +2811,16 @@ class LChunkBuilder V8_FINAL BASE_EMBEDDED { // Methods for setting up define-use relationships. // Return the same instruction that they are passed. - template<int I, int T> - LInstruction* Define(LTemplateInstruction<1, I, T>* instr, - LUnallocated* result); - template<int I, int T> - LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr); - template<int I, int T> - LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr, - int index); - template<int I, int T> - LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr); - template<int I, int T> - LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr, - Register reg); - template<int I, int T> - LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr, - XMMRegister reg); - template<int I, int T> - LInstruction* DefineX87TOS(LTemplateInstruction<1, I, T>* instr); + LInstruction* Define(LTemplateResultInstruction<1>* instr, + LUnallocated* result); + LInstruction* DefineAsRegister(LTemplateResultInstruction<1>* instr); + LInstruction* DefineAsSpilled(LTemplateResultInstruction<1>* instr, + int index); + LInstruction* DefineSameAsFirst(LTemplateResultInstruction<1>* instr); + LInstruction* DefineFixed(LTemplateResultInstruction<1>* instr, + Register reg); + LInstruction* DefineFixedDouble(LTemplateResultInstruction<1>* instr, + XMMRegister reg); // Assigns an environment to an instruction. An instruction which can // deoptimize must have an environment. LInstruction* AssignEnvironment(LInstruction* instr); @@ -2904,11 +2840,8 @@ class LChunkBuilder V8_FINAL BASE_EMBEDDED { HInstruction* hinstr, CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY); - LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env, - int* argument_index_accumulator, - ZoneList<HValue*>* objects_to_materialize); - void VisitInstruction(HInstruction* current); + void AddInstruction(LInstruction* instr, HInstruction* current); void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr); @@ -2922,12 +2855,10 @@ class LChunkBuilder V8_FINAL BASE_EMBEDDED { LPlatformChunk* chunk_; CompilationInfo* info_; HGraph* const graph_; - Zone* zone_; Status status_; HInstruction* current_instruction_; HBasicBlock* current_block_; HBasicBlock* next_block_; - int argument_count_; LAllocator* allocator_; DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); |