2012-01-11 10:35:37 +00:00
|
|
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
2014-04-29 06:42:26 +00:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
#ifndef V8_IA32_LITHIUM_IA32_H_
|
|
|
|
#define V8_IA32_LITHIUM_IA32_H_
|
|
|
|
|
2014-06-03 08:12:43 +00:00
|
|
|
#include "src/hydrogen.h"
|
|
|
|
#include "src/lithium.h"
|
2014-06-20 08:40:11 +00:00
|
|
|
#include "src/lithium-allocator.h"
|
2014-06-03 08:12:43 +00:00
|
|
|
#include "src/safepoint-table.h"
|
|
|
|
#include "src/utils.h"
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
|
2014-07-30 13:54:45 +00:00
|
|
|
namespace compiler {
|
|
|
|
class RCodeVisualizer;
|
|
|
|
}
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
// Forward declarations.
|
|
|
|
class LCodeGen;
|
|
|
|
|
2014-07-29 11:34:08 +00:00
|
|
|
#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
|
|
|
|
V(AccessArgumentsAt) \
|
|
|
|
V(AddI) \
|
|
|
|
V(AllocateBlockContext) \
|
|
|
|
V(Allocate) \
|
|
|
|
V(ApplyArguments) \
|
|
|
|
V(ArgumentsElements) \
|
|
|
|
V(ArgumentsLength) \
|
|
|
|
V(ArithmeticD) \
|
|
|
|
V(ArithmeticT) \
|
|
|
|
V(BitI) \
|
|
|
|
V(BoundsCheck) \
|
|
|
|
V(Branch) \
|
|
|
|
V(CallJSFunction) \
|
|
|
|
V(CallWithDescriptor) \
|
|
|
|
V(CallFunction) \
|
|
|
|
V(CallNew) \
|
|
|
|
V(CallNewArray) \
|
|
|
|
V(CallRuntime) \
|
|
|
|
V(CallStub) \
|
2015-04-28 13:42:54 +00:00
|
|
|
V(CheckArrayBufferNotNeutered) \
|
2014-07-29 11:34:08 +00:00
|
|
|
V(CheckInstanceType) \
|
|
|
|
V(CheckMaps) \
|
|
|
|
V(CheckMapValue) \
|
|
|
|
V(CheckNonSmi) \
|
|
|
|
V(CheckSmi) \
|
|
|
|
V(CheckValue) \
|
|
|
|
V(ClampDToUint8) \
|
|
|
|
V(ClampIToUint8) \
|
|
|
|
V(ClampTToUint8) \
|
|
|
|
V(ClassOfTestAndBranch) \
|
|
|
|
V(CompareMinusZeroAndBranch) \
|
|
|
|
V(CompareNumericAndBranch) \
|
|
|
|
V(CmpObjectEqAndBranch) \
|
|
|
|
V(CmpHoleAndBranch) \
|
|
|
|
V(CmpMapAndBranch) \
|
|
|
|
V(CmpT) \
|
|
|
|
V(ConstantD) \
|
|
|
|
V(ConstantE) \
|
|
|
|
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(FlooringDivByConstI) \
|
|
|
|
V(FlooringDivByPowerOf2I) \
|
|
|
|
V(FlooringDivI) \
|
|
|
|
V(ForInCacheArray) \
|
|
|
|
V(ForInPrepareMap) \
|
|
|
|
V(GetCachedArrayIndex) \
|
|
|
|
V(Goto) \
|
|
|
|
V(HasCachedArrayIndexAndBranch) \
|
2015-08-25 04:48:36 +00:00
|
|
|
V(HasInPrototypeChainAndBranch) \
|
2014-07-29 11:34:08 +00:00
|
|
|
V(HasInstanceTypeAndBranch) \
|
|
|
|
V(InnerAllocatedObject) \
|
|
|
|
V(InstanceOf) \
|
|
|
|
V(InstructionGap) \
|
|
|
|
V(Integer32ToDouble) \
|
|
|
|
V(InvokeFunction) \
|
|
|
|
V(IsConstructCallAndBranch) \
|
|
|
|
V(IsStringAndBranch) \
|
|
|
|
V(IsSmiAndBranch) \
|
|
|
|
V(IsUndetectableAndBranch) \
|
|
|
|
V(Label) \
|
|
|
|
V(LazyBailout) \
|
|
|
|
V(LoadContextSlot) \
|
|
|
|
V(LoadFieldByIndex) \
|
|
|
|
V(LoadFunctionPrototype) \
|
|
|
|
V(LoadGlobalGeneric) \
|
2015-07-20 08:49:09 +00:00
|
|
|
V(LoadGlobalViaContext) \
|
2014-07-29 11:34:08 +00:00
|
|
|
V(LoadKeyed) \
|
|
|
|
V(LoadKeyedGeneric) \
|
|
|
|
V(LoadNamedField) \
|
|
|
|
V(LoadNamedGeneric) \
|
|
|
|
V(LoadRoot) \
|
|
|
|
V(MapEnumLength) \
|
|
|
|
V(MathAbs) \
|
|
|
|
V(MathClz32) \
|
|
|
|
V(MathExp) \
|
|
|
|
V(MathFloor) \
|
|
|
|
V(MathFround) \
|
|
|
|
V(MathLog) \
|
|
|
|
V(MathMinMax) \
|
|
|
|
V(MathPowHalf) \
|
|
|
|
V(MathRound) \
|
|
|
|
V(MathSqrt) \
|
2015-05-12 08:47:15 +00:00
|
|
|
V(MaybeGrowElements) \
|
2014-07-29 11:34:08 +00:00
|
|
|
V(ModByConstI) \
|
|
|
|
V(ModByPowerOf2I) \
|
|
|
|
V(ModI) \
|
|
|
|
V(MulI) \
|
|
|
|
V(NumberTagD) \
|
|
|
|
V(NumberTagI) \
|
|
|
|
V(NumberTagU) \
|
|
|
|
V(NumberUntagD) \
|
|
|
|
V(OsrEntry) \
|
|
|
|
V(Parameter) \
|
|
|
|
V(Power) \
|
2015-09-01 07:06:49 +00:00
|
|
|
V(Prologue) \
|
2014-07-29 11:34:08 +00:00
|
|
|
V(PushArgument) \
|
|
|
|
V(RegExpLiteral) \
|
|
|
|
V(Return) \
|
|
|
|
V(SeqStringGetChar) \
|
|
|
|
V(SeqStringSetChar) \
|
|
|
|
V(ShiftI) \
|
|
|
|
V(SmiTag) \
|
|
|
|
V(SmiUntag) \
|
|
|
|
V(StackCheck) \
|
|
|
|
V(StoreCodeEntry) \
|
|
|
|
V(StoreContextSlot) \
|
|
|
|
V(StoreFrameContext) \
|
2015-07-20 08:49:09 +00:00
|
|
|
V(StoreGlobalViaContext) \
|
2014-07-29 11:34:08 +00:00
|
|
|
V(StoreKeyed) \
|
|
|
|
V(StoreKeyedGeneric) \
|
|
|
|
V(StoreNamedField) \
|
|
|
|
V(StoreNamedGeneric) \
|
|
|
|
V(StringAdd) \
|
|
|
|
V(StringCharCodeAt) \
|
|
|
|
V(StringCharFromCode) \
|
|
|
|
V(StringCompareAndBranch) \
|
|
|
|
V(SubI) \
|
|
|
|
V(TaggedToI) \
|
|
|
|
V(ThisFunction) \
|
|
|
|
V(ToFastProperties) \
|
|
|
|
V(TransitionElementsKind) \
|
|
|
|
V(TrapAllocationMemento) \
|
|
|
|
V(Typeof) \
|
|
|
|
V(TypeofIsAndBranch) \
|
|
|
|
V(Uint32ToDouble) \
|
|
|
|
V(UnknownOSRValue) \
|
2013-07-23 07:31:46 +00:00
|
|
|
V(WrapReceiver)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
|
2014-12-12 10:44:12 +00:00
|
|
|
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
|
2015-04-20 13:08:11 +00:00
|
|
|
Opcode opcode() const final { return LInstruction::k##type; } \
|
|
|
|
void CompileToNative(LCodeGen* generator) final; \
|
|
|
|
const char* Mnemonic() const final { return mnemonic; } \
|
2014-12-12 10:44:12 +00:00
|
|
|
static L##type* cast(LInstruction* instr) { \
|
|
|
|
DCHECK(instr->Is##type()); \
|
|
|
|
return reinterpret_cast<L##type*>(instr); \
|
2010-12-07 11:31:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define DECLARE_HYDROGEN_ACCESSOR(type) \
|
|
|
|
H##type* hydrogen() const { \
|
|
|
|
return H##type::cast(hydrogen_value()); \
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LInstruction : public ZoneObject {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
LInstruction()
|
2011-02-04 13:28:23 +00:00
|
|
|
: environment_(NULL),
|
|
|
|
hydrogen_value_(NULL),
|
2013-08-08 02:16:12 +00:00
|
|
|
bit_field_(IsCallBits::encode(false)) {
|
|
|
|
}
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual ~LInstruction() {}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
virtual void CompileToNative(LCodeGen* generator) = 0;
|
|
|
|
virtual const char* Mnemonic() const = 0;
|
2011-01-10 12:19:15 +00:00
|
|
|
virtual void PrintTo(StringStream* stream);
|
2011-11-02 08:32:40 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream);
|
|
|
|
virtual void PrintOutputOperandTo(StringStream* stream);
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-04-27 11:41:42 +00:00
|
|
|
enum Opcode {
|
|
|
|
// Declare a unique enum value for each instruction.
|
|
|
|
#define DECLARE_OPCODE(type) k##type,
|
2014-07-30 13:54:45 +00:00
|
|
|
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) kAdapter,
|
2011-04-27 11:41:42 +00:00
|
|
|
kNumberOfInstructions
|
|
|
|
#undef DECLARE_OPCODE
|
|
|
|
};
|
|
|
|
|
|
|
|
virtual Opcode opcode() const = 0;
|
|
|
|
|
|
|
|
// Declare non-virtual type testers for all leaf IR classes.
|
|
|
|
#define DECLARE_PREDICATE(type) \
|
|
|
|
bool Is##type() const { return opcode() == k##type; }
|
|
|
|
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
|
|
|
|
#undef DECLARE_PREDICATE
|
|
|
|
|
|
|
|
// Declare virtual predicates for instructions that don't have
|
|
|
|
// an opcode.
|
|
|
|
virtual bool IsGap() const { return false; }
|
2011-01-17 12:22:31 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
virtual bool IsControl() const { return false; }
|
|
|
|
|
2014-07-30 13:54:45 +00:00
|
|
|
// Try deleting this instruction if possible.
|
|
|
|
virtual bool TryDelete() { return false; }
|
|
|
|
|
2011-02-04 13:28:23 +00:00
|
|
|
void set_environment(LEnvironment* env) { environment_ = env; }
|
|
|
|
LEnvironment* environment() const { return environment_; }
|
|
|
|
bool HasEnvironment() const { return environment_ != NULL; }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
|
|
|
|
LPointerMap* pointer_map() const { return pointer_map_.get(); }
|
|
|
|
bool HasPointerMap() const { return pointer_map_.is_set(); }
|
|
|
|
|
|
|
|
void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
|
|
|
|
HValue* hydrogen_value() const { return hydrogen_value_; }
|
|
|
|
|
2013-08-08 02:16:12 +00:00
|
|
|
void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); }
|
|
|
|
bool IsCall() const { return IsCallBits::decode(bit_field_); }
|
2011-02-04 13:28:23 +00:00
|
|
|
|
|
|
|
// Interface to the register allocator and iterators.
|
2013-08-08 02:16:12 +00:00
|
|
|
bool ClobbersTemps() const { return IsCall(); }
|
|
|
|
bool ClobbersRegisters() const { return IsCall(); }
|
2014-04-30 10:24:03 +00:00
|
|
|
virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
|
2014-05-09 13:01:50 +00:00
|
|
|
return IsCall();
|
2012-12-18 16:25:45 +00:00
|
|
|
}
|
2011-02-04 13:28:23 +00:00
|
|
|
|
|
|
|
virtual bool HasResult() const = 0;
|
2013-07-29 11:57:42 +00:00
|
|
|
virtual LOperand* result() const = 0;
|
2011-02-04 13:28:23 +00:00
|
|
|
|
2013-04-09 08:42:57 +00:00
|
|
|
bool HasDoubleRegisterResult();
|
|
|
|
bool HasDoubleRegisterInput();
|
|
|
|
|
2011-02-04 13:28:23 +00:00
|
|
|
LOperand* FirstInput() { return InputAt(0); }
|
|
|
|
LOperand* Output() { return HasResult() ? result() : NULL; }
|
|
|
|
|
2013-04-22 09:48:35 +00:00
|
|
|
virtual bool HasInterestingComment(LCodeGen* gen) const { return true; }
|
|
|
|
|
2011-02-04 13:28:23 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
void VerifyCall();
|
|
|
|
#endif
|
|
|
|
|
2014-07-30 13:54:45 +00:00
|
|
|
virtual int InputCount() = 0;
|
|
|
|
virtual LOperand* InputAt(int i) = 0;
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
private:
|
2012-08-27 09:39:05 +00:00
|
|
|
// Iterator support.
|
|
|
|
friend class InputIterator;
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
friend class TempIterator;
|
|
|
|
virtual int TempCount() = 0;
|
|
|
|
virtual LOperand* TempAt(int i) = 0;
|
|
|
|
|
2013-08-08 02:16:12 +00:00
|
|
|
class IsCallBits: public BitField<bool, 0, 1> {};
|
|
|
|
|
2011-02-04 13:28:23 +00:00
|
|
|
LEnvironment* environment_;
|
2010-12-07 11:31:57 +00:00
|
|
|
SetOncePointer<LPointerMap> pointer_map_;
|
|
|
|
HValue* hydrogen_value_;
|
2013-08-08 02:16:12 +00:00
|
|
|
int bit_field_;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-01-24 09:43:14 +00:00
|
|
|
// R = number of result operands (0 or 1).
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
template<int R>
|
|
|
|
class LTemplateResultInstruction : public LInstruction {
|
2011-01-10 12:19:15 +00:00
|
|
|
public:
|
2011-01-11 15:47:34 +00:00
|
|
|
// Allow 0 or 1 output operands.
|
|
|
|
STATIC_ASSERT(R == 0 || R == 1);
|
2015-04-20 13:08:11 +00:00
|
|
|
bool HasResult() const final { return R != 0 && result() != NULL; }
|
2011-01-17 12:22:31 +00:00
|
|
|
void set_result(LOperand* operand) { results_[0] = operand; }
|
2015-04-20 13:08:11 +00:00
|
|
|
LOperand* result() const override { return results_[0]; }
|
2011-01-11 15:47:34 +00:00
|
|
|
|
2011-01-17 12:22:31 +00:00
|
|
|
protected:
|
2011-06-10 12:09:48 +00:00
|
|
|
EmbeddedContainer<LOperand*, R> results_;
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 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:
|
2011-06-10 12:09:48 +00:00
|
|
|
EmbeddedContainer<LOperand*, I> inputs_;
|
|
|
|
EmbeddedContainer<LOperand*, T> temps_;
|
2012-08-27 09:39:05 +00:00
|
|
|
|
|
|
|
private:
|
2012-09-14 11:55:49 +00:00
|
|
|
// Iterator support.
|
2015-04-20 13:08:11 +00:00
|
|
|
int InputCount() final { return I; }
|
|
|
|
LOperand* InputAt(int i) final { return inputs_[i]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
int TempCount() final { return T; }
|
|
|
|
LOperand* TempAt(int i) final { return temps_[i]; }
|
2011-01-10 12:19:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LGap : public LTemplateInstruction<0, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-04-27 11:41:42 +00:00
|
|
|
explicit LGap(HBasicBlock* block) : block_(block) {
|
2010-12-07 11:31:57 +00:00
|
|
|
parallel_moves_[BEFORE] = NULL;
|
|
|
|
parallel_moves_[START] = NULL;
|
|
|
|
parallel_moves_[END] = NULL;
|
|
|
|
parallel_moves_[AFTER] = NULL;
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:41:42 +00:00
|
|
|
// Can't use the DECLARE-macro here because of sub-classes.
|
2015-04-20 13:08:11 +00:00
|
|
|
bool IsGap() const final { return true; }
|
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-04-27 11:41:42 +00:00
|
|
|
static LGap* cast(LInstruction* instr) {
|
2014-08-04 11:34:54 +00:00
|
|
|
DCHECK(instr->IsGap());
|
2011-04-27 11:41:42 +00:00
|
|
|
return reinterpret_cast<LGap*>(instr);
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
bool IsRedundant() const;
|
|
|
|
|
|
|
|
HBasicBlock* block() const { return block_; }
|
|
|
|
|
|
|
|
enum InnerPosition {
|
|
|
|
BEFORE,
|
|
|
|
START,
|
|
|
|
END,
|
|
|
|
AFTER,
|
|
|
|
FIRST_INNER_POSITION = BEFORE,
|
|
|
|
LAST_INNER_POSITION = AFTER
|
|
|
|
};
|
|
|
|
|
2012-06-11 12:42:31 +00:00
|
|
|
LParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) {
|
|
|
|
if (parallel_moves_[pos] == NULL) {
|
|
|
|
parallel_moves_[pos] = new(zone) LParallelMove(zone);
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
return parallel_moves_[pos];
|
|
|
|
}
|
|
|
|
|
|
|
|
LParallelMove* GetParallelMove(InnerPosition pos) {
|
|
|
|
return parallel_moves_[pos];
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
|
|
|
|
HBasicBlock* block_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LInstructionGap final : public LGap {
|
2011-04-27 11:41:42 +00:00
|
|
|
public:
|
|
|
|
explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
bool HasInterestingComment(LCodeGen* gen) const override {
|
2013-04-22 09:48:35 +00:00
|
|
|
return !IsRedundant();
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:41:42 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LGoto final : public LTemplateInstruction<0, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-09-12 11:54:47 +00:00
|
|
|
explicit LGoto(HBasicBlock* block) : block_(block) { }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
bool HasInterestingComment(LCodeGen* gen) const override;
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
|
|
|
bool IsControl() const override { return true; }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2013-09-12 11:54:47 +00:00
|
|
|
int block_id() const { return block_->block_id(); }
|
2015-04-20 13:08:11 +00:00
|
|
|
bool ClobbersDoubleRegisters(Isolate* isolate) const override {
|
2014-04-30 09:50:58 +00:00
|
|
|
return false;
|
|
|
|
}
|
2013-09-12 11:54:47 +00:00
|
|
|
|
|
|
|
bool jumps_to_join() const { return block_->predecessors()->length() > 1; }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
private:
|
2013-09-12 11:54:47 +00:00
|
|
|
HBasicBlock* block_;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-09-01 07:06:49 +00:00
|
|
|
class LPrologue final : public LTemplateInstruction<0, 0, 0> {
|
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Prologue, "prologue")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLazyBailout final : public LTemplateInstruction<0, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDummy final : public LTemplateInstruction<1, 0, 0> {
|
2013-11-08 14:16:34 +00:00
|
|
|
public:
|
2014-08-12 13:33:35 +00:00
|
|
|
LDummy() {}
|
2013-11-08 14:16:34 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDummyUse final : public LTemplateInstruction<1, 1, 0> {
|
2013-01-17 14:07:47 +00:00
|
|
|
public:
|
|
|
|
explicit LDummyUse(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDeoptimize final : public LTemplateInstruction<0, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2015-04-20 13:08:11 +00:00
|
|
|
bool IsControl() const override { return true; }
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
|
2013-07-23 13:35:10 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLabel final : public LGap {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
explicit LLabel(HBasicBlock* block)
|
2011-04-20 09:08:26 +00:00
|
|
|
: LGap(block), replacement_(NULL) { }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
bool HasInterestingComment(LCodeGen* gen) const override { return false; }
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Label, "label")
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-04-20 09:08:26 +00:00
|
|
|
int block_id() const { return block()->block_id(); }
|
|
|
|
bool is_loop_header() const { return block()->IsLoopHeader(); }
|
2013-04-22 09:48:35 +00:00
|
|
|
bool is_osr_entry() const { return block()->is_osr_entry(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
Label* label() { return &label_; }
|
|
|
|
LLabel* replacement() const { return replacement_; }
|
|
|
|
void set_replacement(LLabel* label) { replacement_ = label; }
|
|
|
|
bool HasReplacement() const { return replacement_ != NULL; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Label label_;
|
|
|
|
LLabel* replacement_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LParameter final : public LTemplateInstruction<1, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2015-04-20 13:08:11 +00:00
|
|
|
bool HasInterestingComment(LCodeGen* gen) const override { return false; }
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCallStub final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-02-10 09:00:50 +00:00
|
|
|
explicit LCallStub(LOperand* context) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CallStub)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2015-04-20 13:08:11 +00:00
|
|
|
bool HasInterestingComment(LCodeGen* gen) const override { return false; }
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-01-21 10:31:28 +00:00
|
|
|
template<int I, int T>
|
2011-01-17 12:22:31 +00:00
|
|
|
class LControlInstruction: public LTemplateInstruction<0, I, T> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-06-20 11:50:50 +00:00
|
|
|
LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
bool IsControl() const final { return true; }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-06-30 14:19:52 +00:00
|
|
|
int SuccessorCount() { return hydrogen()->SuccessorCount(); }
|
|
|
|
HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
|
2013-06-20 11:50:50 +00:00
|
|
|
|
|
|
|
int TrueDestination(LChunk* chunk) {
|
|
|
|
return chunk->LookupDestination(true_block_id());
|
|
|
|
}
|
|
|
|
int FalseDestination(LChunk* chunk) {
|
|
|
|
return chunk->LookupDestination(false_block_id());
|
|
|
|
}
|
|
|
|
|
|
|
|
Label* TrueLabel(LChunk* chunk) {
|
|
|
|
if (true_label_ == NULL) {
|
|
|
|
true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
|
|
|
|
}
|
|
|
|
return true_label_;
|
|
|
|
}
|
|
|
|
Label* FalseLabel(LChunk* chunk) {
|
|
|
|
if (false_label_ == NULL) {
|
|
|
|
false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
|
|
|
|
}
|
|
|
|
return false_label_;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
int true_block_id() { return SuccessorAt(0)->block_id(); }
|
|
|
|
int false_block_id() { return SuccessorAt(1)->block_id(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-01-17 12:22:31 +00:00
|
|
|
private:
|
2011-06-30 14:19:52 +00:00
|
|
|
HControlInstruction* hydrogen() {
|
|
|
|
return HControlInstruction::cast(this->hydrogen_value());
|
|
|
|
}
|
2013-06-20 11:50:50 +00:00
|
|
|
|
|
|
|
Label* false_label_;
|
|
|
|
Label* true_label_;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LWrapReceiver final : public LTemplateInstruction<1, 2, 1> {
|
2012-03-12 12:49:41 +00:00
|
|
|
public:
|
|
|
|
LWrapReceiver(LOperand* receiver,
|
|
|
|
LOperand* function,
|
|
|
|
LOperand* temp) {
|
|
|
|
inputs_[0] = receiver;
|
|
|
|
inputs_[1] = function;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* receiver() { return inputs_[0]; }
|
|
|
|
LOperand* function() { return inputs_[1]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
|
2014-01-30 12:52:49 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(WrapReceiver)
|
2012-03-12 12:49:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LApplyArguments final : public LTemplateInstruction<1, 4, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
LApplyArguments(LOperand* function,
|
|
|
|
LOperand* receiver,
|
|
|
|
LOperand* length,
|
2012-03-12 12:49:41 +00:00
|
|
|
LOperand* elements) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = function;
|
|
|
|
inputs_[1] = receiver;
|
|
|
|
inputs_[2] = length;
|
|
|
|
inputs_[3] = elements;
|
2011-01-11 15:47:34 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-01-17 12:22:31 +00:00
|
|
|
LOperand* function() { return inputs_[0]; }
|
|
|
|
LOperand* receiver() { return inputs_[1]; }
|
|
|
|
LOperand* length() { return inputs_[2]; }
|
|
|
|
LOperand* elements() { return inputs_[3]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LAccessArgumentsAt final : public LTemplateInstruction<1, 3, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-11 15:47:34 +00:00
|
|
|
LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = arguments;
|
|
|
|
inputs_[1] = length;
|
|
|
|
inputs_[2] = index;
|
2011-01-11 15:47:34 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-01-17 12:22:31 +00:00
|
|
|
LOperand* arguments() { return inputs_[0]; }
|
|
|
|
LOperand* length() { return inputs_[1]; }
|
|
|
|
LOperand* index() { return inputs_[2]; }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LArgumentsLength final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
explicit LArgumentsLength(LOperand* elements) {
|
|
|
|
inputs_[0] = elements;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* elements() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LArgumentsElements final : public LTemplateInstruction<1, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
|
2012-04-11 13:40:55 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDebugBreak final : public LTemplateInstruction<0, 0, 0> {
|
2013-05-15 14:24:47 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LModByPowerOf2I final : public LTemplateInstruction<1, 1, 0> {
|
2014-03-07 10:36:28 +00:00
|
|
|
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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LModByConstI final : public LTemplateInstruction<1, 1, 2> {
|
2014-03-10 10:39:17 +00:00
|
|
|
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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LModI final : public LTemplateInstruction<1, 2, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LModI(LOperand* left, LOperand* right, LOperand* temp) {
|
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Mod)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDivByPowerOf2I final : public LTemplateInstruction<1, 1, 0> {
|
2014-03-07 10:36:28 +00:00
|
|
|
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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDivByConstI final : public LTemplateInstruction<1, 1, 2> {
|
2014-03-10 10:39:17 +00:00
|
|
|
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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDivI final : public LTemplateInstruction<1, 2, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2014-04-01 11:42:42 +00:00
|
|
|
LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
|
|
|
|
inputs_[0] = dividend;
|
|
|
|
inputs_[1] = divisor;
|
2011-01-17 12:22:31 +00:00
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2014-04-01 11:42:42 +00:00
|
|
|
LOperand* dividend() { return inputs_[0]; }
|
|
|
|
LOperand* divisor() { return inputs_[1]; }
|
2014-03-07 10:36:28 +00:00
|
|
|
LOperand* temp() { return temps_[0]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
|
2014-03-07 10:36:28 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LFlooringDivByPowerOf2I final : public LTemplateInstruction<1, 1, 0> {
|
2012-06-20 14:08:03 +00:00
|
|
|
public:
|
2014-03-07 10:36:28 +00:00
|
|
|
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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LFlooringDivByConstI final : public LTemplateInstruction<1, 1, 3> {
|
2014-03-07 10:36:28 +00:00
|
|
|
public:
|
2014-03-10 10:39:17 +00:00
|
|
|
LFlooringDivByConstI(LOperand* dividend,
|
|
|
|
int32_t divisor,
|
|
|
|
LOperand* temp1,
|
2014-03-20 13:10:23 +00:00
|
|
|
LOperand* temp2,
|
|
|
|
LOperand* temp3) {
|
2014-03-07 10:36:28 +00:00
|
|
|
inputs_[0] = dividend;
|
|
|
|
divisor_ = divisor;
|
2014-03-10 10:39:17 +00:00
|
|
|
temps_[0] = temp1;
|
|
|
|
temps_[1] = temp2;
|
2014-03-20 13:10:23 +00:00
|
|
|
temps_[2] = temp3;
|
2012-06-20 14:08:03 +00:00
|
|
|
}
|
|
|
|
|
2014-03-07 10:36:28 +00:00
|
|
|
LOperand* dividend() { return inputs_[0]; }
|
|
|
|
int32_t divisor() const { return divisor_; }
|
2014-03-10 10:39:17 +00:00
|
|
|
LOperand* temp1() { return temps_[0]; }
|
|
|
|
LOperand* temp2() { return temps_[1]; }
|
2014-03-20 13:10:23 +00:00
|
|
|
LOperand* temp3() { return temps_[2]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2014-03-07 10:36:28 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
|
2012-06-20 14:08:03 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
|
2014-03-07 10:36:28 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
int32_t divisor_;
|
2012-06-20 14:08:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LFlooringDivI final : public LTemplateInstruction<1, 2, 1> {
|
2014-04-01 11:42:42 +00:00
|
|
|
public:
|
|
|
|
LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
|
|
|
|
inputs_[0] = dividend;
|
|
|
|
inputs_[1] = divisor;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* dividend() { return inputs_[0]; }
|
|
|
|
LOperand* divisor() { return inputs_[1]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMulI final : public LTemplateInstruction<1, 2, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LMulI(LOperand* left, LOperand* right, LOperand* temp) {
|
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Mul)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCompareNumericAndBranch final : public LControlInstruction<2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-07-05 10:40:14 +00:00
|
|
|
LCompareNumericAndBranch(LOperand* left, LOperand* right) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
|
|
|
|
2013-07-05 10:40:14 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
|
|
|
|
"compare-numeric-and-branch")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-01-17 12:22:31 +00:00
|
|
|
Token::Value op() const { return hydrogen()->token(); }
|
|
|
|
bool is_double() const {
|
2012-11-14 15:59:45 +00:00
|
|
|
return hydrogen()->representation().IsDouble();
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMathFloor final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-04-11 13:27:06 +00:00
|
|
|
explicit LMathFloor(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMathRound final : public LTemplateInstruction<1, 1, 1> {
|
2013-04-11 13:27:06 +00:00
|
|
|
public:
|
2013-11-08 10:58:51 +00:00
|
|
|
LMathRound(LOperand* value, LOperand* temp) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = value;
|
2013-04-11 13:27:06 +00:00
|
|
|
temps_[0] = temp;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2013-04-11 13:27:06 +00:00
|
|
|
LOperand* temp() { return temps_[0]; }
|
2014-07-29 11:34:08 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
2011-07-04 14:13:08 +00:00
|
|
|
|
2013-04-11 13:27:06 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
|
2013-04-11 13:27:06 +00:00
|
|
|
};
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2013-04-11 13:27:06 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMathFround final : public LTemplateInstruction<1, 1, 0> {
|
2014-07-29 11:34:08 +00:00
|
|
|
public:
|
|
|
|
explicit LMathFround(LOperand* value) { inputs_[0] = value; }
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2014-07-30 09:55:21 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathFround, "math-fround")
|
2014-07-29 11:34:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMathAbs final : public LTemplateInstruction<1, 2, 0> {
|
2013-04-11 13:27:06 +00:00
|
|
|
public:
|
|
|
|
LMathAbs(LOperand* context, LOperand* value) {
|
|
|
|
inputs_[1] = context;
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* context() { return inputs_[1]; }
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMathLog final : public LTemplateInstruction<1, 1, 0> {
|
2013-04-11 13:27:06 +00:00
|
|
|
public:
|
|
|
|
explicit LMathLog(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMathClz32 final : public LTemplateInstruction<1, 1, 0> {
|
2014-02-19 13:51:49 +00:00
|
|
|
public:
|
|
|
|
explicit LMathClz32(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMathExp final : public LTemplateInstruction<1, 1, 2> {
|
2012-11-26 13:12:35 +00:00
|
|
|
public:
|
|
|
|
LMathExp(LOperand* value,
|
|
|
|
LOperand* temp1,
|
|
|
|
LOperand* temp2) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp1;
|
|
|
|
temps_[1] = temp2;
|
|
|
|
ExternalReference::InitializeMathExpData();
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp1() { return temps_[0]; }
|
|
|
|
LOperand* temp2() { return temps_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMathSqrt final : public LTemplateInstruction<1, 1, 0> {
|
2011-12-05 15:58:25 +00:00
|
|
|
public:
|
2013-04-11 13:27:06 +00:00
|
|
|
explicit LMathSqrt(LOperand* value) {
|
2011-12-05 15:58:25 +00:00
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2013-04-11 13:27:06 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
|
2011-12-05 15:58:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMathPowHalf final : public LTemplateInstruction<1, 1, 1> {
|
2013-03-04 08:44:42 +00:00
|
|
|
public:
|
2013-11-08 10:58:51 +00:00
|
|
|
LMathPowHalf(LOperand* value, LOperand* temp) {
|
2013-03-04 08:44:42 +00:00
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2013-04-11 13:27:06 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
|
2013-03-04 08:44:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCmpObjectEqAndBranch final : public LControlInstruction<2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-06-21 11:18:15 +00:00
|
|
|
LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
|
|
|
|
2013-08-14 08:54:27 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCmpHoleAndBranch final : public LControlInstruction<1, 0> {
|
2013-08-14 08:54:27 +00:00
|
|
|
public:
|
|
|
|
explicit LCmpHoleAndBranch(LOperand* object) {
|
|
|
|
inputs_[0] = object;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* object() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
|
2011-05-11 12:50:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCompareMinusZeroAndBranch final : public LControlInstruction<1, 1> {
|
2013-11-12 11:53:13 +00:00
|
|
|
public:
|
|
|
|
LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
|
|
|
|
"cmp-minus-zero-and-branch")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LIsStringAndBranch final : public LControlInstruction<1, 1> {
|
2011-11-17 13:57:55 +00:00
|
|
|
public:
|
|
|
|
LIsStringAndBranch(LOperand* value, LOperand* temp) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2011-11-17 13:57:55 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
|
2013-06-26 17:37:55 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
|
2011-11-17 13:57:55 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-11-17 13:57:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LIsSmiAndBranch final : public LControlInstruction<1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
explicit LIsSmiAndBranch(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
|
2011-06-30 14:19:52 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LIsUndetectableAndBranch final : public LControlInstruction<1, 1> {
|
2011-05-11 11:53:43 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
|
2011-05-11 11:53:43 +00:00
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2011-05-11 11:53:43 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
|
|
|
|
"is-undetectable-and-branch")
|
2013-06-26 17:37:55 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
|
2011-05-11 11:53:43 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-05-11 11:53:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LStringCompareAndBranch final : public LControlInstruction<3, 0> {
|
2011-11-17 13:57:55 +00:00
|
|
|
public:
|
|
|
|
LStringCompareAndBranch(LOperand* context, LOperand* left, LOperand* right) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = left;
|
|
|
|
inputs_[2] = right;
|
|
|
|
}
|
|
|
|
|
2013-11-08 10:58:51 +00:00
|
|
|
LOperand* context() { return inputs_[1]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[1]; }
|
|
|
|
LOperand* right() { return inputs_[2]; }
|
|
|
|
|
2011-11-17 13:57:55 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
|
|
|
|
"string-compare-and-branch")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-11-17 13:57:55 +00:00
|
|
|
|
|
|
|
Token::Value op() const { return hydrogen()->token(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LHasInstanceTypeAndBranch final : public LControlInstruction<1, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LHasInstanceTypeAndBranch(LOperand* value, LOperand* temp) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
|
|
|
|
"has-instance-type-and-branch")
|
2011-06-30 14:19:52 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LGetCachedArrayIndex final : public LTemplateInstruction<1, 1, 0> {
|
2011-03-03 09:33:08 +00:00
|
|
|
public:
|
|
|
|
explicit LGetCachedArrayIndex(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2011-03-03 09:33:08 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LHasCachedArrayIndexAndBranch final : public LControlInstruction<1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
|
|
|
|
"has-cached-array-index-and-branch")
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LIsConstructCallAndBranch final : public LControlInstruction<0, 1> {
|
2011-02-08 10:08:47 +00:00
|
|
|
public:
|
|
|
|
explicit LIsConstructCallAndBranch(LOperand* temp) {
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2011-02-08 10:08:47 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
|
|
|
|
"is-construct-call-and-branch")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LClassOfTestAndBranch final : public LControlInstruction<1, 2> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
temps_[1] = temp2;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
LOperand* temp2() { return temps_[1]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch,
|
|
|
|
"class-of-test-and-branch")
|
2011-06-30 14:19:52 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCmpT final : public LTemplateInstruction<1, 3, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-09-23 18:57:32 +00:00
|
|
|
LCmpT(LOperand* context, LOperand* left, LOperand* right) {
|
2011-07-04 14:13:08 +00:00
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = left;
|
|
|
|
inputs_[2] = right;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2013-09-23 18:57:32 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-06-08 12:17:58 +00:00
|
|
|
Strength strength() { return hydrogen()->strength(); }
|
2015-05-12 15:23:53 +00:00
|
|
|
|
2013-11-08 10:58:51 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
2010-12-07 11:31:57 +00:00
|
|
|
Token::Value op() const { return hydrogen()->token(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LInstanceOf final : public LTemplateInstruction<1, 3, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-02-10 09:00:50 +00:00
|
|
|
LInstanceOf(LOperand* context, LOperand* left, LOperand* right) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = left;
|
|
|
|
inputs_[2] = right;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-08-25 04:48:36 +00:00
|
|
|
LOperand* context() const { return inputs_[0]; }
|
|
|
|
LOperand* left() const { return inputs_[1]; }
|
|
|
|
LOperand* right() const { return inputs_[2]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-08-25 04:48:36 +00:00
|
|
|
class LHasInPrototypeChainAndBranch final : public LControlInstruction<2, 1> {
|
2011-01-05 11:17:37 +00:00
|
|
|
public:
|
2015-08-25 04:48:36 +00:00
|
|
|
LHasInPrototypeChainAndBranch(LOperand* object, LOperand* prototype,
|
|
|
|
LOperand* scratch) {
|
|
|
|
inputs_[0] = object;
|
|
|
|
inputs_[1] = prototype;
|
|
|
|
temps_[0] = scratch;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2011-01-05 11:17:37 +00:00
|
|
|
|
2015-08-25 04:48:36 +00:00
|
|
|
LOperand* object() const { return inputs_[0]; }
|
|
|
|
LOperand* prototype() const { return inputs_[1]; }
|
|
|
|
LOperand* scratch() const { return temps_[0]; }
|
2012-04-26 12:43:00 +00:00
|
|
|
|
2015-08-25 04:48:36 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(HasInPrototypeChainAndBranch,
|
|
|
|
"has-in-prototype-chain-and-branch")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(HasInPrototypeChainAndBranch)
|
2011-01-05 11:17:37 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LBoundsCheck final : public LTemplateInstruction<0, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LBoundsCheck(LOperand* index, LOperand* length) {
|
|
|
|
inputs_[0] = index;
|
|
|
|
inputs_[1] = length;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-01-17 12:22:31 +00:00
|
|
|
LOperand* index() { return inputs_[0]; }
|
|
|
|
LOperand* length() { return inputs_[1]; }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
|
2012-07-20 11:00:33 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LBitI final : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-10-31 13:06:26 +00:00
|
|
|
LBitI(LOperand* left, LOperand* right) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
|
2011-10-31 13:06:26 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Bitwise)
|
2012-09-14 11:55:49 +00:00
|
|
|
|
|
|
|
Token::Value op() const { return hydrogen()->op(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LShiftI final : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
|
2011-01-17 12:22:31 +00:00
|
|
|
: op_(op), can_deopt_(can_deopt) {
|
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
Token::Value op() const { return op_; }
|
|
|
|
bool can_deopt() const { return can_deopt_; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
private:
|
|
|
|
Token::Value op_;
|
|
|
|
bool can_deopt_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LSubI final : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LSubI(LOperand* left, LOperand* right) {
|
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Sub)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LConstantI final : public LTemplateInstruction<1, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
|
2011-02-08 10:45:21 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Constant)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-02-08 10:45:21 +00:00
|
|
|
int32_t value() const { return hydrogen()->Integer32Value(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LConstantS final : public LTemplateInstruction<1, 0, 0> {
|
2013-05-29 10:47:55 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Constant)
|
|
|
|
|
|
|
|
Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LConstantD final : public LTemplateInstruction<1, 0, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-02-09 12:39:15 +00:00
|
|
|
explicit LConstantD(LOperand* temp) {
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
|
2011-02-08 10:45:21 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Constant)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-01-21 08:52:00 +00:00
|
|
|
uint64_t bits() const { return hydrogen()->DoubleValueAsBits(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LConstantE final : public LTemplateInstruction<1, 0, 0> {
|
2013-07-29 13:56:51 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Constant)
|
|
|
|
|
|
|
|
ExternalReference value() const {
|
|
|
|
return hydrogen()->ExternalReferenceValue();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LConstantT final : public LTemplateInstruction<1, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
|
2011-02-08 10:45:21 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Constant)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2013-09-09 07:57:23 +00:00
|
|
|
Handle<Object> value(Isolate* isolate) const {
|
|
|
|
return hydrogen()->handle(isolate);
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LBranch final : public LControlInstruction<1, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2012-09-14 11:55:49 +00:00
|
|
|
LBranch(LOperand* value, LOperand* temp) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = value;
|
2011-07-28 13:33:51 +00:00
|
|
|
temps_[0] = temp;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
|
2011-06-30 14:19:52 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Branch)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCmpMapAndBranch final : public LControlInstruction<1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
explicit LCmpMapAndBranch(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
|
2011-01-20 12:56:34 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CompareMap)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2013-09-19 17:02:57 +00:00
|
|
|
Handle<Map> map() const { return hydrogen()->map().handle(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMapEnumLength final : public LTemplateInstruction<1, 1, 0> {
|
2012-08-28 14:20:50 +00:00
|
|
|
public:
|
|
|
|
explicit LMapEnumLength(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2012-08-28 14:20:50 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDateField final : public LTemplateInstruction<1, 1, 1> {
|
2012-03-09 11:11:55 +00:00
|
|
|
public:
|
2012-03-09 12:07:29 +00:00
|
|
|
LDateField(LOperand* date, LOperand* temp, Smi* index)
|
2012-03-09 11:11:55 +00:00
|
|
|
: index_(index) {
|
|
|
|
inputs_[0] = date;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* date() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2012-03-09 12:07:29 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
|
2012-03-09 11:11:55 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(DateField)
|
|
|
|
|
2012-03-09 12:07:29 +00:00
|
|
|
Smi* index() const { return index_; }
|
2012-03-09 11:11:55 +00:00
|
|
|
|
|
|
|
private:
|
2012-03-09 12:07:29 +00:00
|
|
|
Smi* index_;
|
2012-03-09 11:11:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> {
|
2013-11-07 13:43:03 +00:00
|
|
|
public:
|
|
|
|
LSeqStringGetChar(LOperand* string, LOperand* index) {
|
|
|
|
inputs_[0] = string;
|
|
|
|
inputs_[1] = index;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* string() const { return inputs_[0]; }
|
|
|
|
LOperand* index() const { return inputs_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar, "seq-string-get-char")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(SeqStringGetChar)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LSeqStringSetChar final : public LTemplateInstruction<1, 4, 0> {
|
2012-12-05 15:49:22 +00:00
|
|
|
public:
|
2013-11-19 16:41:07 +00:00
|
|
|
LSeqStringSetChar(LOperand* context,
|
|
|
|
LOperand* string,
|
2012-12-05 15:49:22 +00:00
|
|
|
LOperand* index,
|
2013-11-06 13:09:22 +00:00
|
|
|
LOperand* value) {
|
2013-11-19 16:41:07 +00:00
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = string;
|
|
|
|
inputs_[2] = index;
|
|
|
|
inputs_[3] = value;
|
2012-12-05 15:49:22 +00:00
|
|
|
}
|
|
|
|
|
2013-11-19 16:41:07 +00:00
|
|
|
LOperand* string() { return inputs_[1]; }
|
|
|
|
LOperand* index() { return inputs_[2]; }
|
|
|
|
LOperand* value() { return inputs_[3]; }
|
2012-12-05 15:49:22 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LAddI final : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LAddI(LOperand* left, LOperand* right) {
|
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
|
|
|
|
2013-05-08 08:37:24 +00:00
|
|
|
static bool UseLea(HAdd* add) {
|
|
|
|
return !add->CheckFlag(HValue::kCanOverflow) &&
|
|
|
|
add->BetterLeftOperand()->UseCount() > 1;
|
|
|
|
}
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Add)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LMathMinMax final : public LTemplateInstruction<1, 2, 0> {
|
2012-08-06 14:28:27 +00:00
|
|
|
public:
|
|
|
|
LMathMinMax(LOperand* left, LOperand* right) {
|
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
|
|
|
|
2013-04-11 13:27:06 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
|
2012-08-06 14:28:27 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LPower final : public LTemplateInstruction<1, 2, 0> {
|
2010-12-08 14:32:40 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LPower(LOperand* left, LOperand* right) {
|
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
}
|
2010-12-08 14:32:40 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
|
|
|
|
2010-12-08 14:32:40 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Power, "power")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Power)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LArithmeticD final : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
|
2011-01-17 12:22:31 +00:00
|
|
|
: op_(op) {
|
|
|
|
inputs_[0] = left;
|
|
|
|
inputs_[1] = right;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* left() { return inputs_[0]; }
|
|
|
|
LOperand* right() { return inputs_[1]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
Token::Value op() const { return op_; }
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
Opcode opcode() const override { return LInstruction::kArithmeticD; }
|
|
|
|
void CompileToNative(LCodeGen* generator) override;
|
|
|
|
const char* Mnemonic() const override;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
Token::Value op_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LArithmeticT final : public LTemplateInstruction<1, 3, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
LArithmeticT(Token::Value op,
|
|
|
|
LOperand* context,
|
|
|
|
LOperand* left,
|
|
|
|
LOperand* right)
|
2011-01-17 12:22:31 +00:00
|
|
|
: op_(op) {
|
2011-07-04 14:13:08 +00:00
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = left;
|
|
|
|
inputs_[2] = right;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* left() { return inputs_[1]; }
|
|
|
|
LOperand* right() { return inputs_[2]; }
|
2015-05-06 10:40:27 +00:00
|
|
|
Token::Value op() const { return op_; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
Opcode opcode() const override { return LInstruction::kArithmeticT; }
|
|
|
|
void CompileToNative(LCodeGen* generator) override;
|
|
|
|
const char* Mnemonic() const override;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-05-06 10:40:27 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
|
|
|
|
2015-06-08 12:17:58 +00:00
|
|
|
Strength strength() { return hydrogen()->strength(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
Token::Value op_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LReturn final : public LTemplateInstruction<0, 3, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-11-08 10:58:51 +00:00
|
|
|
explicit LReturn(LOperand* value,
|
|
|
|
LOperand* context,
|
2013-03-08 21:07:55 +00:00
|
|
|
LOperand* parameter_count) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = value;
|
2012-12-28 16:25:38 +00:00
|
|
|
inputs_[1] = context;
|
2013-03-08 21:07:55 +00:00
|
|
|
inputs_[2] = parameter_count;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2013-03-08 21:07:55 +00:00
|
|
|
bool has_constant_parameter_count() {
|
|
|
|
return parameter_count()->IsConstantOperand();
|
|
|
|
}
|
|
|
|
LConstantOperand* constant_parameter_count() {
|
2014-08-04 11:34:54 +00:00
|
|
|
DCHECK(has_constant_parameter_count());
|
2013-03-08 21:07:55 +00:00
|
|
|
return LConstantOperand::cast(parameter_count());
|
|
|
|
}
|
|
|
|
LOperand* parameter_count() { return inputs_[2]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Return, "return")
|
2013-04-25 16:00:32 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Return)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLoadNamedField final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-05-08 15:02:08 +00:00
|
|
|
explicit LLoadNamedField(LOperand* object) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = object;
|
2013-05-08 15:02:08 +00:00
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* object() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
|
2011-03-24 10:11:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLoadNamedGeneric final : public LTemplateInstruction<1, 2, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2014-07-21 11:19:56 +00:00
|
|
|
LLoadNamedGeneric(LOperand* context, LOperand* object, LOperand* vector) {
|
2011-02-10 09:00:50 +00:00
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = object;
|
2014-07-21 11:19:56 +00:00
|
|
|
temps_[0] = vector;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* object() { return inputs_[1]; }
|
2014-07-21 11:19:56 +00:00
|
|
|
LOperand* temp_vector() { return temps_[0]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
|
|
|
|
|
|
|
|
Handle<Object> name() const { return hydrogen()->name(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLoadFunctionPrototype final : public LTemplateInstruction<1, 1, 1> {
|
2010-12-22 15:43:32 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LLoadFunctionPrototype(LOperand* function, LOperand* temp) {
|
|
|
|
inputs_[0] = function;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2010-12-22 15:43:32 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* function() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-22 15:43:32 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLoadRoot final : public LTemplateInstruction<1, 0, 0> {
|
2013-09-19 06:08:13 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
|
|
|
|
|
|
|
|
Heap::RootListIndex index() const { return hydrogen()->index(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLoadKeyed final : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2012-11-02 09:18:53 +00:00
|
|
|
LLoadKeyed(LOperand* elements, LOperand* key) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = elements;
|
|
|
|
inputs_[1] = key;
|
|
|
|
}
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* elements() { return inputs_[0]; }
|
|
|
|
LOperand* key() { return inputs_[1]; }
|
2012-11-02 09:18:53 +00:00
|
|
|
ElementsKind elements_kind() const {
|
|
|
|
return hydrogen()->elements_kind();
|
|
|
|
}
|
2014-01-16 17:08:45 +00:00
|
|
|
bool is_fixed_typed_array() const {
|
|
|
|
return hydrogen()->is_fixed_typed_array();
|
|
|
|
}
|
2011-07-19 13:04:00 +00:00
|
|
|
|
2012-11-02 09:18:53 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
|
2011-07-19 13:04:00 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2014-05-22 08:37:50 +00:00
|
|
|
uint32_t base_offset() const { return hydrogen()->base_offset(); }
|
2012-12-18 16:25:45 +00:00
|
|
|
bool key_is_smi() {
|
|
|
|
return hydrogen()->key()->representation().IsTagged();
|
|
|
|
}
|
2011-07-19 13:04:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-11-13 10:53:34 +00:00
|
|
|
inline static bool ExternalArrayOpRequiresTemp(
|
|
|
|
Representation key_representation,
|
|
|
|
ElementsKind elements_kind) {
|
2012-07-20 11:00:33 +00:00
|
|
|
// Operations that require the key to be divided by two to be converted into
|
|
|
|
// an index cannot fold the scale operation into a load and need an extra
|
|
|
|
// temp register to do the work.
|
2013-05-24 08:52:35 +00:00
|
|
|
return key_representation.IsSmi() &&
|
2015-07-28 09:29:34 +00:00
|
|
|
(elements_kind == UINT8_ELEMENTS || elements_kind == INT8_ELEMENTS ||
|
|
|
|
elements_kind == UINT8_CLAMPED_ELEMENTS);
|
2012-07-20 11:00:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLoadKeyedGeneric final : public LTemplateInstruction<1, 3, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2014-07-21 11:19:56 +00:00
|
|
|
LLoadKeyedGeneric(LOperand* context, LOperand* obj, LOperand* key,
|
|
|
|
LOperand* vector) {
|
2011-02-10 09:00:50 +00:00
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = obj;
|
|
|
|
inputs_[2] = key;
|
2014-07-21 11:19:56 +00:00
|
|
|
temps_[0] = vector;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-02-10 09:00:50 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* object() { return inputs_[1]; }
|
|
|
|
LOperand* key() { return inputs_[2]; }
|
2014-07-21 11:19:56 +00:00
|
|
|
LOperand* temp_vector() { return temps_[0]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
|
2014-07-21 11:19:56 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadKeyedGeneric)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLoadGlobalGeneric final : public LTemplateInstruction<1, 2, 1> {
|
2011-04-01 11:54:04 +00:00
|
|
|
public:
|
2014-07-21 11:19:56 +00:00
|
|
|
LLoadGlobalGeneric(LOperand* context, LOperand* global_object,
|
|
|
|
LOperand* vector) {
|
2011-04-01 11:54:04 +00:00
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = global_object;
|
2014-07-21 11:19:56 +00:00
|
|
|
temps_[0] = vector;
|
2011-04-01 11:54:04 +00:00
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* global_object() { return inputs_[1]; }
|
2014-07-21 11:19:56 +00:00
|
|
|
LOperand* temp_vector() { return temps_[0]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2011-04-01 11:54:04 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
|
|
|
|
|
|
|
|
Handle<Object> name() const { return hydrogen()->name(); }
|
2015-07-13 13:39:26 +00:00
|
|
|
TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-07-20 08:49:09 +00:00
|
|
|
class LLoadGlobalViaContext final : public LTemplateInstruction<1, 1, 1> {
|
|
|
|
public:
|
|
|
|
explicit LLoadGlobalViaContext(LOperand* context) { inputs_[0] = context; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalViaContext, "load-global-via-context")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalViaContext)
|
|
|
|
|
|
|
|
void PrintDataTo(StringStream* stream) override;
|
|
|
|
|
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
|
|
|
|
int depth() const { return hydrogen()->depth(); }
|
|
|
|
int slot_index() const { return hydrogen()->slot_index(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLoadContextSlot final : public LTemplateInstruction<1, 1, 0> {
|
2011-01-17 08:11:03 +00:00
|
|
|
public:
|
2011-02-03 13:10:28 +00:00
|
|
|
explicit LLoadContextSlot(LOperand* context) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
|
2011-01-17 08:11:03 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
|
|
|
|
|
2011-01-17 12:22:31 +00:00
|
|
|
int slot_index() { return hydrogen()->slot_index(); }
|
2011-01-17 08:11:03 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-01-17 08:11:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LStoreContextSlot final : public LTemplateInstruction<0, 2, 1> {
|
2011-02-03 13:10:28 +00:00
|
|
|
public:
|
|
|
|
LStoreContextSlot(LOperand* context, LOperand* value, LOperand* temp) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* value() { return inputs_[1]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2011-02-03 13:10:28 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
|
|
|
|
|
|
|
|
int slot_index() { return hydrogen()->slot_index(); }
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-02-03 13:10:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LPushArgument final : public LTemplateInstruction<0, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
explicit LPushArgument(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDrop final : public LTemplateInstruction<0, 0, 0> {
|
2012-04-11 13:40:55 +00:00
|
|
|
public:
|
|
|
|
explicit LDrop(int count) : count_(count) { }
|
|
|
|
|
|
|
|
int count() const { return count_; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
|
|
|
|
|
|
|
|
private:
|
|
|
|
int count_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LStoreCodeEntry final : public LTemplateInstruction<0, 2, 0> {
|
2013-08-27 11:55:08 +00:00
|
|
|
public:
|
|
|
|
LStoreCodeEntry(LOperand* function, LOperand* code_object) {
|
|
|
|
inputs_[0] = function;
|
2014-06-18 11:17:52 +00:00
|
|
|
inputs_[1] = code_object;
|
2013-08-27 11:55:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* function() { return inputs_[0]; }
|
2014-06-18 11:17:52 +00:00
|
|
|
LOperand* code_object() { return inputs_[1]; }
|
2013-08-27 11:55:08 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2013-08-27 11:55:08 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LInnerAllocatedObject final : public LTemplateInstruction<1, 2, 0> {
|
2013-03-13 11:05:48 +00:00
|
|
|
public:
|
2013-12-02 11:24:31 +00:00
|
|
|
LInnerAllocatedObject(LOperand* base_object, LOperand* offset) {
|
2013-03-13 11:05:48 +00:00
|
|
|
inputs_[0] = base_object;
|
2013-12-02 11:24:31 +00:00
|
|
|
inputs_[1] = offset;
|
2013-03-13 11:05:48 +00:00
|
|
|
}
|
|
|
|
|
2013-12-02 11:24:31 +00:00
|
|
|
LOperand* base_object() const { return inputs_[0]; }
|
|
|
|
LOperand* offset() const { return inputs_[1]; }
|
2013-03-13 11:05:48 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2013-03-13 11:05:48 +00:00
|
|
|
|
2013-12-02 11:24:31 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
|
2013-03-13 11:05:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LThisFunction final : public LTemplateInstruction<1, 0, 0> {
|
2011-10-19 11:41:22 +00:00
|
|
|
public:
|
2011-05-31 11:54:46 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
|
2011-10-19 11:41:22 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
|
2011-05-31 11:54:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LContext final : public LTemplateInstruction<1, 0, 0> {
|
2011-02-03 13:10:28 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Context, "context")
|
2013-02-04 12:01:59 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Context)
|
2011-02-03 13:10:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDeclareGlobals final : public LTemplateInstruction<0, 1, 0> {
|
2012-02-14 14:14:51 +00:00
|
|
|
public:
|
|
|
|
explicit LDeclareGlobals(LOperand* context) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
|
2012-02-14 14:14:51 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCallJSFunction final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
explicit LCallJSFunction(LOperand* function) {
|
|
|
|
inputs_[0] = function;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* function() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
int arity() const { return hydrogen()->argument_count() - 1; }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCallWithDescriptor final : public LTemplateResultInstruction<1> {
|
2011-04-15 07:58:22 +00:00
|
|
|
public:
|
2014-09-03 10:51:51 +00:00
|
|
|
LCallWithDescriptor(CallInterfaceDescriptor descriptor,
|
2014-09-01 12:15:25 +00:00
|
|
|
const ZoneList<LOperand*>& operands, Zone* zone)
|
2015-07-01 08:45:05 +00:00
|
|
|
: inputs_(descriptor.GetRegisterParameterCount() +
|
|
|
|
kImplicitRegisterParameterCount,
|
|
|
|
zone) {
|
|
|
|
DCHECK(descriptor.GetRegisterParameterCount() +
|
|
|
|
kImplicitRegisterParameterCount ==
|
|
|
|
operands.length());
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
inputs_.AddAll(operands, zone);
|
2011-04-15 07:58:22 +00:00
|
|
|
}
|
|
|
|
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
LOperand* target() const { return inputs_[0]; }
|
2011-04-15 07:58:22 +00:00
|
|
|
|
2014-09-08 12:51:29 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
|
|
|
|
|
2015-07-01 08:45:05 +00:00
|
|
|
// The target and context are passed as implicit parameters that are not
|
|
|
|
// explicitly listed in the descriptor.
|
|
|
|
static const int kImplicitRegisterParameterCount = 2;
|
|
|
|
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
private:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-04-15 07:58:22 +00:00
|
|
|
|
|
|
|
int arity() const { return hydrogen()->argument_count() - 1; }
|
|
|
|
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
ZoneList<LOperand*> inputs_;
|
2011-04-15 07:58:22 +00:00
|
|
|
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
// Iterator support.
|
2015-04-20 13:08:11 +00:00
|
|
|
int InputCount() final { return inputs_.length(); }
|
|
|
|
LOperand* InputAt(int i) final { return inputs_[i]; }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
int TempCount() final { return 0; }
|
|
|
|
LOperand* TempAt(int i) final { return NULL; }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LInvokeFunction final : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
LInvokeFunction(LOperand* context, LOperand* function) {
|
2011-02-10 09:00:50 +00:00
|
|
|
inputs_[0] = context;
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
inputs_[1] = function;
|
2011-02-10 09:00:50 +00:00
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
LOperand* function() { return inputs_[1]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
int arity() const { return hydrogen()->argument_count() - 1; }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCallFunction final : public LTemplateInstruction<1, 2, 2> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2015-01-28 09:03:05 +00:00
|
|
|
LCallFunction(LOperand* context, LOperand* function, LOperand* slot,
|
|
|
|
LOperand* vector) {
|
2011-02-10 09:00:50 +00:00
|
|
|
inputs_[0] = context;
|
2011-11-08 14:39:37 +00:00
|
|
|
inputs_[1] = function;
|
2015-01-28 09:03:05 +00:00
|
|
|
temps_[0] = slot;
|
|
|
|
temps_[1] = vector;
|
2011-02-10 09:00:50 +00:00
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* function() { return inputs_[1]; }
|
2015-01-28 09:03:05 +00:00
|
|
|
LOperand* temp_slot() { return temps_[0]; }
|
|
|
|
LOperand* temp_vector() { return temps_[1]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CallFunction)
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-11-08 14:39:37 +00:00
|
|
|
int arity() const { return hydrogen()->argument_count() - 1; }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCallNew final : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-02-10 09:00:50 +00:00
|
|
|
LCallNew(LOperand* context, LOperand* constructor) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = constructor;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* constructor() { return inputs_[1]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CallNew)
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
int arity() const { return hydrogen()->argument_count() - 1; }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCallNewArray final : public LTemplateInstruction<1, 2, 0> {
|
2013-03-01 16:06:34 +00:00
|
|
|
public:
|
|
|
|
LCallNewArray(LOperand* context, LOperand* constructor) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = constructor;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* constructor() { return inputs_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2013-03-01 16:06:34 +00:00
|
|
|
|
|
|
|
int arity() const { return hydrogen()->argument_count() - 1; }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCallRuntime final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
explicit LCallRuntime(LOperand* context) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
}
|
2012-09-14 11:55:49 +00:00
|
|
|
|
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
bool ClobbersDoubleRegisters(Isolate* isolate) const override {
|
2013-10-01 11:56:42 +00:00
|
|
|
return save_doubles() == kDontSaveFPRegs;
|
|
|
|
}
|
|
|
|
|
2011-03-18 20:35:07 +00:00
|
|
|
const Runtime::Function* function() const { return hydrogen()->function(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
int arity() const { return hydrogen()->argument_count(); }
|
2013-10-01 11:56:42 +00:00
|
|
|
SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LInteger32ToDouble final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
explicit LInteger32ToDouble(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LUint32ToDouble final : public LTemplateInstruction<1, 1, 0> {
|
2012-08-22 15:44:17 +00:00
|
|
|
public:
|
2014-05-26 06:41:21 +00:00
|
|
|
explicit LUint32ToDouble(LOperand* value) {
|
2012-08-22 15:44:17 +00:00
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2012-08-22 15:44:17 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LNumberTagI final : public LTemplateInstruction<1, 1, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2014-03-04 12:45:00 +00:00
|
|
|
LNumberTagI(LOperand* value, LOperand* temp) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = value;
|
2014-03-04 12:45:00 +00:00
|
|
|
temps_[0] = temp;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
2014-03-04 12:45:00 +00:00
|
|
|
LOperand* temp() { return temps_[0]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LNumberTagU final : public LTemplateInstruction<1, 1, 1> {
|
2012-08-22 15:44:17 +00:00
|
|
|
public:
|
2014-05-26 06:41:21 +00:00
|
|
|
LNumberTagU(LOperand* value, LOperand* temp) {
|
2012-08-22 15:44:17 +00:00
|
|
|
inputs_[0] = value;
|
2014-05-26 06:41:21 +00:00
|
|
|
temps_[0] = temp;
|
2012-08-22 15:44:17 +00:00
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
2014-05-26 06:41:21 +00:00
|
|
|
LOperand* temp() { return temps_[0]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2012-08-22 15:44:17 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LNumberTagD final : public LTemplateInstruction<1, 1, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-24 09:43:14 +00:00
|
|
|
LNumberTagD(LOperand* value, LOperand* temp) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
|
2013-02-04 12:01:59 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Change)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Sometimes truncating conversion from a tagged value to an int32.
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDoubleToI final : public LTemplateInstruction<1, 1, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LDoubleToI(LOperand* value, LOperand* temp) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
|
2011-05-26 12:07:22 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
bool truncating() { return hydrogen()->CanTruncateToInt32(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDoubleToSmi final : public LTemplateInstruction<1, 1, 0> {
|
2013-05-23 08:32:07 +00:00
|
|
|
public:
|
|
|
|
explicit LDoubleToSmi(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
// Truncating conversion from a tagged value to an int32.
|
2015-04-20 13:08:11 +00:00
|
|
|
class LTaggedToI final : public LTemplateInstruction<1, 1, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LTaggedToI(LOperand* value, LOperand* temp) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
|
2013-09-16 15:24:49 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Change)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
bool truncating() { return hydrogen()->CanTruncateToInt32(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LSmiTag final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
explicit LSmiTag(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
|
2014-03-13 06:11:52 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Change)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LNumberUntagD final : public LTemplateInstruction<1, 1, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2012-01-11 15:43:33 +00:00
|
|
|
explicit LNumberUntagD(LOperand* value, LOperand* temp) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = value;
|
2012-01-11 15:43:33 +00:00
|
|
|
temps_[0] = temp;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
|
2011-06-09 12:27:28 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Change);
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LSmiUntag final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LSmiUntag(LOperand* value, bool needs_check)
|
|
|
|
: needs_check_(needs_check) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
|
|
|
|
|
|
|
|
bool needs_check() const { return needs_check_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool needs_check_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LStoreNamedField final : public LTemplateInstruction<0, 2, 2> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2012-05-29 16:39:26 +00:00
|
|
|
LStoreNamedField(LOperand* obj,
|
|
|
|
LOperand* val,
|
2014-05-20 13:03:25 +00:00
|
|
|
LOperand* temp,
|
|
|
|
LOperand* temp_map) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = obj;
|
|
|
|
inputs_[1] = val;
|
2011-02-23 11:19:50 +00:00
|
|
|
temps_[0] = temp;
|
2014-05-20 13:03:25 +00:00
|
|
|
temps_[1] = temp_map;
|
2011-01-11 15:47:34 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* object() { return inputs_[0]; }
|
|
|
|
LOperand* value() { return inputs_[1]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
2014-05-20 13:03:25 +00:00
|
|
|
LOperand* temp_map() { return temps_[1]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2011-02-23 11:19:50 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-06-26 07:53:21 +00:00
|
|
|
class LStoreNamedGeneric final : public LTemplateInstruction<0, 3, 2> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2015-06-26 07:53:21 +00:00
|
|
|
LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value,
|
|
|
|
LOperand* slot, LOperand* vector) {
|
2011-02-10 09:00:50 +00:00
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = object;
|
|
|
|
inputs_[2] = value;
|
2015-06-26 07:53:21 +00:00
|
|
|
temps_[0] = slot;
|
|
|
|
temps_[1] = vector;
|
2011-02-10 09:00:50 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* object() { return inputs_[1]; }
|
|
|
|
LOperand* value() { return inputs_[2]; }
|
2015-06-26 07:53:21 +00:00
|
|
|
LOperand* temp_slot() { return temps_[0]; }
|
|
|
|
LOperand* temp_vector() { return temps_[1]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
|
2011-01-11 11:41:01 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
|
2011-02-10 09:00:50 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-02-10 09:00:50 +00:00
|
|
|
Handle<Object> name() const { return hydrogen()->name(); }
|
2015-02-04 09:34:05 +00:00
|
|
|
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-07-20 08:49:09 +00:00
|
|
|
class LStoreGlobalViaContext final : public LTemplateInstruction<0, 2, 0> {
|
|
|
|
public:
|
|
|
|
LStoreGlobalViaContext(LOperand* context, LOperand* value) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* value() { return inputs_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalViaContext,
|
|
|
|
"store-global-via-context")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalViaContext)
|
|
|
|
|
|
|
|
void PrintDataTo(StringStream* stream) override;
|
|
|
|
|
|
|
|
int depth() { return hydrogen()->depth(); }
|
|
|
|
int slot_index() { return hydrogen()->slot_index(); }
|
|
|
|
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LStoreKeyed final : public LTemplateInstruction<0, 3, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2012-11-02 09:18:53 +00:00
|
|
|
LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = obj;
|
|
|
|
inputs_[1] = key;
|
|
|
|
inputs_[2] = val;
|
2011-01-11 15:47:34 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2014-01-16 17:08:45 +00:00
|
|
|
bool is_fixed_typed_array() const {
|
|
|
|
return hydrogen()->is_fixed_typed_array();
|
|
|
|
}
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* elements() { return inputs_[0]; }
|
|
|
|
LOperand* key() { return inputs_[1]; }
|
|
|
|
LOperand* value() { return inputs_[2]; }
|
2012-11-02 09:18:53 +00:00
|
|
|
ElementsKind elements_kind() const {
|
|
|
|
return hydrogen()->elements_kind();
|
|
|
|
}
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2012-11-02 09:18:53 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
|
2011-07-19 13:04:00 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2014-05-22 08:37:50 +00:00
|
|
|
uint32_t base_offset() const { return hydrogen()->base_offset(); }
|
2012-04-11 14:08:11 +00:00
|
|
|
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-06-26 07:53:21 +00:00
|
|
|
class LStoreKeyedGeneric final : public LTemplateInstruction<0, 4, 2> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2015-06-26 07:53:21 +00:00
|
|
|
LStoreKeyedGeneric(LOperand* context, LOperand* object, LOperand* key,
|
|
|
|
LOperand* value, LOperand* slot, LOperand* vector) {
|
2011-02-10 09:00:50 +00:00
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = object;
|
|
|
|
inputs_[2] = key;
|
|
|
|
inputs_[3] = value;
|
2015-06-26 07:53:21 +00:00
|
|
|
temps_[0] = slot;
|
|
|
|
temps_[1] = vector;
|
2011-02-10 09:00:50 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* object() { return inputs_[1]; }
|
|
|
|
LOperand* key() { return inputs_[2]; }
|
|
|
|
LOperand* value() { return inputs_[3]; }
|
2015-06-26 07:53:21 +00:00
|
|
|
LOperand* temp_slot() { return temps_[0]; }
|
|
|
|
LOperand* temp_vector() { return temps_[1]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
|
2011-04-08 14:30:10 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
|
2011-02-10 09:00:50 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-02-23 11:19:50 +00:00
|
|
|
|
2015-02-04 09:34:05 +00:00
|
|
|
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LTransitionElementsKind final : public LTemplateInstruction<0, 2, 2> {
|
2011-10-19 12:10:18 +00:00
|
|
|
public:
|
|
|
|
LTransitionElementsKind(LOperand* object,
|
2013-02-04 12:01:59 +00:00
|
|
|
LOperand* context,
|
2011-10-19 12:10:18 +00:00
|
|
|
LOperand* new_map_temp,
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* temp) {
|
2011-10-19 12:10:18 +00:00
|
|
|
inputs_[0] = object;
|
2013-02-04 12:01:59 +00:00
|
|
|
inputs_[1] = context;
|
2011-10-19 12:10:18 +00:00
|
|
|
temps_[0] = new_map_temp;
|
2012-09-14 11:55:49 +00:00
|
|
|
temps_[1] = temp;
|
2011-10-19 12:10:18 +00:00
|
|
|
}
|
|
|
|
|
2013-02-04 12:01:59 +00:00
|
|
|
LOperand* context() { return inputs_[1]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* object() { return inputs_[0]; }
|
|
|
|
LOperand* new_map_temp() { return temps_[0]; }
|
|
|
|
LOperand* temp() { return temps_[1]; }
|
|
|
|
|
2011-10-19 12:10:18 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
|
|
|
|
"transition-elements-kind")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2011-10-19 12:10:18 +00:00
|
|
|
|
2013-09-20 12:25:00 +00:00
|
|
|
Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
|
|
|
|
Handle<Map> transitioned_map() {
|
|
|
|
return hydrogen()->transitioned_map().handle();
|
|
|
|
}
|
2013-01-23 13:52:00 +00:00
|
|
|
ElementsKind from_kind() { return hydrogen()->from_kind(); }
|
|
|
|
ElementsKind to_kind() { return hydrogen()->to_kind(); }
|
2011-10-19 12:10:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LTrapAllocationMemento final : public LTemplateInstruction<0, 1, 1> {
|
2013-02-04 12:01:59 +00:00
|
|
|
public:
|
|
|
|
LTrapAllocationMemento(LOperand* object,
|
|
|
|
LOperand* temp) {
|
|
|
|
inputs_[0] = object;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* object() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento,
|
|
|
|
"trap-allocation-memento")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-05-12 08:47:15 +00:00
|
|
|
class LMaybeGrowElements final : public LTemplateInstruction<1, 5, 0> {
|
|
|
|
public:
|
|
|
|
LMaybeGrowElements(LOperand* context, LOperand* object, LOperand* elements,
|
|
|
|
LOperand* key, LOperand* current_capacity) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = object;
|
|
|
|
inputs_[2] = elements;
|
|
|
|
inputs_[3] = key;
|
|
|
|
inputs_[4] = current_capacity;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* object() { return inputs_[1]; }
|
|
|
|
LOperand* elements() { return inputs_[2]; }
|
|
|
|
LOperand* key() { return inputs_[3]; }
|
|
|
|
LOperand* current_capacity() { return inputs_[4]; }
|
|
|
|
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(MaybeGrowElements)
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MaybeGrowElements, "maybe-grow-elements")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LStringAdd final : public LTemplateInstruction<1, 3, 0> {
|
2011-04-15 06:39:36 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
LStringAdd(LOperand* context, LOperand* left, LOperand* right) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = left;
|
|
|
|
inputs_[2] = right;
|
2011-04-15 06:39:36 +00:00
|
|
|
}
|
|
|
|
|
2011-07-04 14:13:08 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* left() { return inputs_[1]; }
|
|
|
|
LOperand* right() { return inputs_[2]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StringAdd)
|
2011-04-15 06:39:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LStringCharCodeAt final : public LTemplateInstruction<1, 3, 0> {
|
2011-01-19 20:05:22 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = string;
|
|
|
|
inputs_[2] = index;
|
2011-01-19 20:05:22 +00:00
|
|
|
}
|
|
|
|
|
2011-07-04 14:13:08 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* string() { return inputs_[1]; }
|
|
|
|
LOperand* index() { return inputs_[2]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
|
2011-01-19 20:05:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LStringCharFromCode final : public LTemplateInstruction<1, 2, 0> {
|
2011-03-14 15:36:00 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
LStringCharFromCode(LOperand* context, LOperand* char_code) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = char_code;
|
2011-03-14 15:36:00 +00:00
|
|
|
}
|
|
|
|
|
2011-07-04 14:13:08 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* char_code() { return inputs_[1]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
|
2011-03-14 15:36:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCheckValue final : public LTemplateInstruction<0, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-08-28 14:16:57 +00:00
|
|
|
explicit LCheckValue(LOperand* value) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-09-27 11:42:02 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2013-08-28 14:16:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CheckValue)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-28 13:42:54 +00:00
|
|
|
class LCheckArrayBufferNotNeutered final
|
|
|
|
: public LTemplateInstruction<0, 1, 1> {
|
|
|
|
public:
|
|
|
|
explicit LCheckArrayBufferNotNeutered(LOperand* view, LOperand* scratch) {
|
|
|
|
inputs_[0] = view;
|
|
|
|
temps_[0] = scratch;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* view() { return inputs_[0]; }
|
|
|
|
LOperand* scratch() { return temps_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered,
|
|
|
|
"check-array-buffer-not-neutered")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCheckInstanceType final : public LTemplateInstruction<0, 1, 1> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
LCheckInstanceType(LOperand* value, LOperand* temp) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCheckMaps final : public LTemplateInstruction<0, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2014-05-05 11:03:14 +00:00
|
|
|
explicit LCheckMaps(LOperand* value = NULL) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2012-03-23 16:37:54 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCheckSmi final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-03-16 16:28:06 +00:00
|
|
|
explicit LCheckSmi(LOperand* value) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2011-03-16 16:28:06 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
|
|
|
|
};
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-03-16 16:28:06 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LClampDToUint8 final : public LTemplateInstruction<1, 1, 0> {
|
2011-05-16 14:10:56 +00:00
|
|
|
public:
|
2011-05-17 07:22:01 +00:00
|
|
|
explicit LClampDToUint8(LOperand* value) {
|
2011-05-16 14:10:56 +00:00
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* unclamped() { return inputs_[0]; }
|
|
|
|
|
2011-05-17 07:22:01 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
|
2011-05-16 14:10:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LClampIToUint8 final : public LTemplateInstruction<1, 1, 0> {
|
2011-05-16 14:10:56 +00:00
|
|
|
public:
|
|
|
|
explicit LClampIToUint8(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* unclamped() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LClampTToUint8 final : public LTemplateInstruction<1, 1, 1> {
|
2011-05-16 14:10:56 +00:00
|
|
|
public:
|
2013-09-27 12:43:37 +00:00
|
|
|
LClampTToUint8(LOperand* value, LOperand* temp_xmm) {
|
2011-05-16 14:10:56 +00:00
|
|
|
inputs_[0] = value;
|
2013-09-27 12:43:37 +00:00
|
|
|
temps_[0] = temp_xmm;
|
2011-05-16 14:10:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* unclamped() { return inputs_[0]; }
|
2013-09-27 12:43:37 +00:00
|
|
|
LOperand* temp_xmm() { return temps_[0]; }
|
2011-05-16 14:10:56 +00:00
|
|
|
|
2011-05-17 07:22:01 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
|
2011-05-16 14:10:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCheckNonSmi final : public LTemplateInstruction<0, 1, 0> {
|
2011-03-16 16:28:06 +00:00
|
|
|
public:
|
|
|
|
explicit LCheckNonSmi(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
2010-12-07 11:31:57 +00:00
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2011-03-16 16:28:06 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
|
2013-06-26 17:37:55 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LDoubleBits final : public LTemplateInstruction<1, 1, 0> {
|
2014-03-07 14:58:41 +00:00
|
|
|
public:
|
|
|
|
explicit LDoubleBits(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(DoubleBits)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LConstructDouble final : public LTemplateInstruction<1, 2, 0> {
|
2014-03-07 14:58:41 +00:00
|
|
|
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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LAllocate final : public LTemplateInstruction<1, 2, 1> {
|
2013-02-04 12:01:59 +00:00
|
|
|
public:
|
|
|
|
LAllocate(LOperand* context, LOperand* size, LOperand* temp) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = size;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* size() { return inputs_[1]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Allocate)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LRegExpLiteral final : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
explicit LRegExpLiteral(LOperand* context) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LToFastProperties final : public LTemplateInstruction<1, 1, 0> {
|
2011-03-21 12:25:31 +00:00
|
|
|
public:
|
|
|
|
explicit LToFastProperties(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2011-03-21 12:25:31 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LTypeof final : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
LTypeof(LOperand* context, LOperand* value) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = value;
|
2011-01-17 12:22:31 +00:00
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* value() { return inputs_[1]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LTypeofIsAndBranch final : public LControlInstruction<1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-01-17 12:22:31 +00:00
|
|
|
explicit LTypeofIsAndBranch(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
|
2011-06-30 14:19:52 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-01-17 12:22:31 +00:00
|
|
|
Handle<String> type_literal() { return hydrogen()->type_literal(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
void PrintDataTo(StringStream* stream) override;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LOsrEntry final : public LTemplateInstruction<0, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2015-04-20 13:08:11 +00:00
|
|
|
bool HasInterestingComment(LCodeGen* gen) const override { return false; }
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LStackCheck final : public LTemplateInstruction<0, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
explicit LStackCheck(LOperand* context) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
|
2011-06-27 12:12:27 +00:00
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StackCheck)
|
|
|
|
|
|
|
|
Label* done_label() { return &done_label_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Label done_label_;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LForInPrepareMap final : public LTemplateInstruction<1, 2, 0> {
|
2012-02-22 12:47:42 +00:00
|
|
|
public:
|
|
|
|
LForInPrepareMap(LOperand* context, LOperand* object) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = object;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* object() { return inputs_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LForInCacheArray final : public LTemplateInstruction<1, 1, 0> {
|
2012-02-22 12:47:42 +00:00
|
|
|
public:
|
|
|
|
explicit LForInCacheArray(LOperand* map) {
|
|
|
|
inputs_[0] = map;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* map() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
|
|
|
|
|
|
|
|
int idx() {
|
|
|
|
return HForInCacheArray::cast(this->hydrogen_value())->idx();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LCheckMapValue final : public LTemplateInstruction<0, 2, 0> {
|
2012-02-22 12:47:42 +00:00
|
|
|
public:
|
|
|
|
LCheckMapValue(LOperand* value, LOperand* map) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
inputs_[1] = map;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* map() { return inputs_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LLoadFieldByIndex final : public LTemplateInstruction<1, 2, 0> {
|
2012-02-22 12:47:42 +00:00
|
|
|
public:
|
|
|
|
LLoadFieldByIndex(LOperand* object, LOperand* index) {
|
|
|
|
inputs_[0] = object;
|
|
|
|
inputs_[1] = index;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* object() { return inputs_[0]; }
|
|
|
|
LOperand* index() { return inputs_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-06-05 07:33:01 +00:00
|
|
|
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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
class LChunkBuilder;
|
2015-04-20 13:08:11 +00:00
|
|
|
class LPlatformChunk final : public LChunk {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2012-07-12 15:29:14 +00:00
|
|
|
LPlatformChunk(CompilationInfo* info, HGraph* graph)
|
|
|
|
: LChunk(info, graph),
|
2012-07-11 14:42:17 +00:00
|
|
|
num_double_slots_(0) { }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2013-09-28 00:48:08 +00:00
|
|
|
int GetNextSpillIndex(RegisterKind kind);
|
|
|
|
LOperand* GetNextSpillSlot(RegisterKind kind);
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2012-06-12 10:22:33 +00:00
|
|
|
int num_double_slots() const { return num_double_slots_; }
|
2012-06-11 12:42:31 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
private:
|
2012-06-12 10:22:33 +00:00
|
|
|
int num_double_slots_;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-04-20 13:08:11 +00:00
|
|
|
class LChunkBuilder final : public LChunkBuilderBase {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-03-07 11:52:36 +00:00
|
|
|
LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
|
2014-09-24 07:08:27 +00:00
|
|
|
: LChunkBuilderBase(info, graph),
|
2010-12-07 11:31:57 +00:00
|
|
|
current_instruction_(NULL),
|
|
|
|
current_block_(NULL),
|
|
|
|
next_block_(NULL),
|
2014-09-24 07:08:27 +00:00
|
|
|
allocator_(allocator) {}
|
2014-04-30 09:50:58 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
// Build the sequence for the graph.
|
2012-07-12 15:29:14 +00:00
|
|
|
LPlatformChunk* Build();
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
|
2013-04-11 13:27:06 +00:00
|
|
|
LInstruction* DoMathFloor(HUnaryMathOperation* instr);
|
|
|
|
LInstruction* DoMathRound(HUnaryMathOperation* instr);
|
2014-07-29 11:34:08 +00:00
|
|
|
LInstruction* DoMathFround(HUnaryMathOperation* instr);
|
2013-04-11 13:27:06 +00:00
|
|
|
LInstruction* DoMathAbs(HUnaryMathOperation* instr);
|
|
|
|
LInstruction* DoMathLog(HUnaryMathOperation* instr);
|
|
|
|
LInstruction* DoMathExp(HUnaryMathOperation* instr);
|
|
|
|
LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
|
|
|
|
LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
|
2014-02-19 13:51:49 +00:00
|
|
|
LInstruction* DoMathClz32(HUnaryMathOperation* instr);
|
2014-03-07 10:36:28 +00:00
|
|
|
LInstruction* DoDivByPowerOf2I(HDiv* instr);
|
2014-03-10 10:39:17 +00:00
|
|
|
LInstruction* DoDivByConstI(HDiv* instr);
|
2014-04-01 11:42:42 +00:00
|
|
|
LInstruction* DoDivI(HDiv* instr);
|
2014-03-07 10:36:28 +00:00
|
|
|
LInstruction* DoModByPowerOf2I(HMod* instr);
|
2014-03-10 10:39:17 +00:00
|
|
|
LInstruction* DoModByConstI(HMod* instr);
|
2014-03-07 10:36:28 +00:00
|
|
|
LInstruction* DoModI(HMod* instr);
|
|
|
|
LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
|
|
|
|
LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
|
2014-04-01 11:42:42 +00:00
|
|
|
LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
|
2013-04-11 13:27:06 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
private:
|
|
|
|
// Methods for getting operands for Use / Define / Temp.
|
|
|
|
LUnallocated* ToUnallocated(Register reg);
|
|
|
|
LUnallocated* ToUnallocated(XMMRegister reg);
|
|
|
|
|
|
|
|
// Methods for setting up define-use relationships.
|
2011-01-17 12:22:31 +00:00
|
|
|
MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
|
|
|
|
MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
|
|
|
|
MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
|
|
|
|
XMMRegister fixed_register);
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
// A value that is guaranteed to be allocated to a register.
|
|
|
|
// Operand created by UseRegister is guaranteed to be live until the end of
|
|
|
|
// instruction. This means that register allocator will not reuse it's
|
|
|
|
// register for any other operand inside instruction.
|
|
|
|
// Operand created by UseRegisterAtStart is guaranteed to be live only at
|
|
|
|
// instruction start. Register allocator is free to assign the same register
|
|
|
|
// to some other operand used inside instruction (i.e. temporary or
|
|
|
|
// output).
|
2011-01-17 12:22:31 +00:00
|
|
|
MUST_USE_RESULT LOperand* UseRegister(HValue* value);
|
|
|
|
MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2011-01-17 12:54:52 +00:00
|
|
|
// An input operand in a register that may be trashed.
|
2011-01-17 12:22:31 +00:00
|
|
|
MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
|
2011-01-17 12:54:52 +00:00
|
|
|
|
|
|
|
// An input operand in a register or stack slot.
|
2011-01-17 12:22:31 +00:00
|
|
|
MUST_USE_RESULT LOperand* Use(HValue* value);
|
|
|
|
MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
|
2011-01-17 12:54:52 +00:00
|
|
|
|
|
|
|
// An input operand in a register, stack slot or a constant operand.
|
2011-01-17 12:22:31 +00:00
|
|
|
MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
|
|
|
|
MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
|
2011-01-17 12:54:52 +00:00
|
|
|
|
2013-11-06 13:09:22 +00:00
|
|
|
// An input operand in a fixed register or a constant operand.
|
|
|
|
MUST_USE_RESULT LOperand* UseFixedOrConstant(HValue* value,
|
|
|
|
Register fixed_register);
|
|
|
|
|
2011-01-17 12:54:52 +00:00
|
|
|
// An input operand in a register or a constant operand.
|
2011-01-17 12:22:31 +00:00
|
|
|
MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
|
|
|
|
MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
|
|
|
|
|
2013-04-26 14:04:07 +00:00
|
|
|
// An input operand in a constant operand.
|
|
|
|
MUST_USE_RESULT LOperand* UseConstant(HValue* value);
|
|
|
|
|
2011-01-17 12:54:52 +00:00
|
|
|
// An input operand in register, stack slot or a constant operand.
|
|
|
|
// Will not be moved to a register even if one is freely available.
|
2015-04-20 13:08:11 +00:00
|
|
|
MUST_USE_RESULT LOperand* UseAny(HValue* value) override;
|
2011-01-17 12:54:52 +00:00
|
|
|
|
2011-01-17 12:22:31 +00:00
|
|
|
// Temporary operand that must be in a register.
|
|
|
|
MUST_USE_RESULT LUnallocated* TempRegister();
|
|
|
|
MUST_USE_RESULT LOperand* FixedTemp(Register reg);
|
|
|
|
MUST_USE_RESULT LOperand* FixedTemp(XMMRegister reg);
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
// Methods for setting up define-use relationships.
|
|
|
|
// Return the same instruction that they are passed.
|
This is a preview of a first step towards unification of the hydrogen
call machinery. The change replaces CallNamed, CallKeyed,
CallConstantFunction and CallKnownGlobal hydrogen instructions with two
new instructions with a more lower level semantics:
1. CallJSFunction for direct calls of JSFunction objects (no
argument adaptation)
2. CallWithDescriptor for calls of a given Code object according to
the supplied calling convention.
Details:
CallJSFunction should be straightforward, the main difference from the
existing InvokeFunction instruction is the absence of argument adaptor
handling. (As a next step, we will replace InvokeFunction with an
equivalent hydrogen code.)
For CallWithDescriptor, the calling conventions are represented by a
tweaked version of CallStubInterfaceDescriptor. In addition to the
parameter-register mapping, we also define parameter-representation
mapping there. The CallWithDescriptor instruction has variable number of
parameters now - this required some simple tweaks in Lithium, which
assumed fixed number of arguments in some places.
The calling conventions used in the calls are initialized in the
CallDescriptors class (code-stubs.h, <arch>/code-stubs-<arch>.cc), and
they live in a new table in the Isolate class. I should say I am not
quite sure about Representation::Integer32() representation for some of
the params of ArgumentAdaptorCall - it is not clear to me wether the
params could not end up on the stack and thus confuse the GC.
The change also includes an earlier small change to argument adaptor
(https://codereview.chromium.org/98463007) that avoids passing a naked
pointer to the code entry as a parameter. I am sorry for packaging that
with an already biggish change.
Performance implications:
Locally, I see a small regression (.2% or so). It is hard to say where
exactly it comes from, but I do see inefficient call sequences to the
adaptor trampoline. For example:
;;; <@78,#24> constant-t
bf85aa515a mov edi,0x5a51aa85 ;; debug: position 29
;;; <@72,#53> load-named-field
8b7717 mov esi,[edi+0x17] ;; debug: position 195
;;; <@80,#51> constant-s
b902000000 mov ecx,0x2 ;; debug: position 195
;;; <@81,#51> gap
894df0 mov [ebp+0xf0],ecx
;;; <@82,#103> constant-i
bb01000000 mov ebx,0x1
;;; <@84,#102> constant-i
b902000000 mov ecx,0x2
;;; <@85,#102> gap
89d8 mov eax,ebx
89cb mov ebx,ecx
8b4df0 mov ecx,[ebp+0xf0]
;;; <@86,#58> call-with-descriptor
e8ef57fcff call ArgumentsAdaptorTrampoline (0x2d80e6e0) ;; code: BUILTIN
Note the silly handling of ecx; the hydrogen for this code is:
0 4 s27 Constant 1 range:1_1 <|@
0 3 t30 Constant 0x5bc1aa85 <JS Function xyz (SharedFunctionInfo 0x5bc1a919)> type:object <|@
0 1 t36 LoadNamedField t30.[in-object]@24 <|@
0 1 t38 Constant 0x2300e6a1 <Code> <|@
0 1 i102 Constant 2 range:2_2 <|@
0 1 i103 Constant 1 range:1_1 <|@
0 2 t41 CallWithDescriptor t38 t30 t36 s27 i103 i102 #2 changes[*] <|@
BUG=
R=verwaest@chromium.org, danno@chromium.org
Review URL: https://codereview.chromium.org/104663004
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18626 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2014-01-15 17:00:35 +00:00
|
|
|
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);
|
2011-08-16 13:32:27 +00:00
|
|
|
// Assigns an environment to an instruction. An instruction which can
|
|
|
|
// deoptimize must have an environment.
|
2010-12-07 11:31:57 +00:00
|
|
|
LInstruction* AssignEnvironment(LInstruction* instr);
|
2011-08-16 13:32:27 +00:00
|
|
|
// Assigns a pointer map to an instruction. An instruction which can
|
|
|
|
// trigger a GC or a lazy deoptimization must have a pointer map.
|
2010-12-07 11:31:57 +00:00
|
|
|
LInstruction* AssignPointerMap(LInstruction* instr);
|
|
|
|
|
|
|
|
enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
|
|
|
|
|
2013-11-19 16:41:07 +00:00
|
|
|
LOperand* GetSeqStringSetCharOperand(HSeqStringSetChar* instr);
|
|
|
|
|
2011-08-16 13:32:27 +00:00
|
|
|
// Marks a call for the register allocator. Assigns a pointer map to
|
|
|
|
// support GC and lazy deoptimization. Assigns an environment to support
|
|
|
|
// eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
|
2010-12-07 11:31:57 +00:00
|
|
|
LInstruction* MarkAsCall(
|
|
|
|
LInstruction* instr,
|
|
|
|
HInstruction* hinstr,
|
|
|
|
CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
|
2011-01-26 08:03:48 +00:00
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
void VisitInstruction(HInstruction* current);
|
2014-05-23 13:15:07 +00:00
|
|
|
void AddInstruction(LInstruction* instr, HInstruction* current);
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
|
|
|
|
LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
|
|
|
|
LInstruction* DoArithmeticD(Token::Value op,
|
|
|
|
HArithmeticBinaryOperation* instr);
|
|
|
|
LInstruction* DoArithmeticT(Token::Value op,
|
2013-09-16 15:24:49 +00:00
|
|
|
HBinaryOperation* instr);
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2013-04-09 08:42:57 +00:00
|
|
|
LOperand* GetStoreKeyedValueOperand(HStoreKeyed* instr);
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
HInstruction* current_instruction_;
|
|
|
|
HBasicBlock* current_block_;
|
|
|
|
HBasicBlock* next_block_;
|
|
|
|
LAllocator* allocator_;
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
|
|
|
|
};
|
|
|
|
|
|
|
|
#undef DECLARE_HYDROGEN_ACCESSOR
|
|
|
|
#undef DECLARE_CONCRETE_INSTRUCTION
|
|
|
|
|
|
|
|
} } // namespace v8::internal
|
|
|
|
|
|
|
|
#endif // V8_IA32_LITHIUM_IA32_H_
|