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_
|
|
|
|
|
|
|
|
#include "hydrogen.h"
|
|
|
|
#include "lithium-allocator.h"
|
2011-01-07 11:49:22 +00:00
|
|
|
#include "lithium.h"
|
2010-12-07 11:31:57 +00:00
|
|
|
#include "safepoint-table.h"
|
2011-06-10 12:09:48 +00:00
|
|
|
#include "utils.h"
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
|
|
|
|
// Forward declarations.
|
|
|
|
class LCodeGen;
|
|
|
|
|
|
|
|
#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
|
|
|
|
V(AccessArgumentsAt) \
|
|
|
|
V(AddI) \
|
2013-02-04 12:01:59 +00:00
|
|
|
V(Allocate) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(ApplyArguments) \
|
|
|
|
V(ArgumentsElements) \
|
|
|
|
V(ArgumentsLength) \
|
|
|
|
V(ArithmeticD) \
|
|
|
|
V(ArithmeticT) \
|
2014-05-09 08:28:25 +00:00
|
|
|
V(ArrayShift) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(BitI) \
|
|
|
|
V(BoundsCheck) \
|
|
|
|
V(Branch) \
|
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
|
|
|
V(CallJSFunction) \
|
|
|
|
V(CallWithDescriptor) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(CallFunction) \
|
|
|
|
V(CallNew) \
|
2013-03-01 16:06:34 +00:00
|
|
|
V(CallNewArray) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(CallRuntime) \
|
|
|
|
V(CallStub) \
|
|
|
|
V(CheckInstanceType) \
|
2012-03-23 16:37:54 +00:00
|
|
|
V(CheckMaps) \
|
2013-07-23 07:31:46 +00:00
|
|
|
V(CheckMapValue) \
|
2011-03-16 16:28:06 +00:00
|
|
|
V(CheckNonSmi) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(CheckSmi) \
|
2013-08-28 14:16:57 +00:00
|
|
|
V(CheckValue) \
|
2011-05-17 07:22:01 +00:00
|
|
|
V(ClampDToUint8) \
|
2011-05-16 14:10:56 +00:00
|
|
|
V(ClampIToUint8) \
|
2011-05-17 07:22:01 +00:00
|
|
|
V(ClampTToUint8) \
|
2011-02-03 13:10:28 +00:00
|
|
|
V(ClassOfTestAndBranch) \
|
2013-11-12 11:53:13 +00:00
|
|
|
V(CompareMinusZeroAndBranch) \
|
2013-07-05 10:40:14 +00:00
|
|
|
V(CompareNumericAndBranch) \
|
2011-06-21 11:18:15 +00:00
|
|
|
V(CmpObjectEqAndBranch) \
|
2013-08-14 08:54:27 +00:00
|
|
|
V(CmpHoleAndBranch) \
|
2011-06-20 10:19:00 +00:00
|
|
|
V(CmpMapAndBranch) \
|
2013-09-23 18:57:32 +00:00
|
|
|
V(CmpT) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(ConstantD) \
|
2013-07-29 13:56:51 +00:00
|
|
|
V(ConstantE) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(ConstantI) \
|
2013-05-29 10:47:55 +00:00
|
|
|
V(ConstantS) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(ConstantT) \
|
2014-03-07 14:58:41 +00:00
|
|
|
V(ConstructDouble) \
|
2011-02-03 13:10:28 +00:00
|
|
|
V(Context) \
|
2013-07-23 07:31:46 +00:00
|
|
|
V(DateField) \
|
2013-05-15 14:24:47 +00:00
|
|
|
V(DebugBreak) \
|
2012-02-14 14:14:51 +00:00
|
|
|
V(DeclareGlobals) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(Deoptimize) \
|
2014-03-10 10:39:17 +00:00
|
|
|
V(DivByConstI) \
|
2014-03-07 10:36:28 +00:00
|
|
|
V(DivByPowerOf2I) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(DivI) \
|
2014-03-07 14:58:41 +00:00
|
|
|
V(DoubleBits) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(DoubleToI) \
|
2013-05-23 08:32:07 +00:00
|
|
|
V(DoubleToSmi) \
|
2013-07-23 07:31:46 +00:00
|
|
|
V(Drop) \
|
2013-11-08 14:16:34 +00:00
|
|
|
V(Dummy) \
|
2013-01-17 14:07:47 +00:00
|
|
|
V(DummyUse) \
|
2014-03-07 10:36:28 +00:00
|
|
|
V(FlooringDivByConstI) \
|
|
|
|
V(FlooringDivByPowerOf2I) \
|
2014-04-01 11:42:42 +00:00
|
|
|
V(FlooringDivI) \
|
2013-07-23 07:31:46 +00:00
|
|
|
V(ForInCacheArray) \
|
|
|
|
V(ForInPrepareMap) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(FunctionLiteral) \
|
2011-03-03 09:33:08 +00:00
|
|
|
V(GetCachedArrayIndex) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(Goto) \
|
2011-02-03 13:10:28 +00:00
|
|
|
V(HasCachedArrayIndexAndBranch) \
|
|
|
|
V(HasInstanceTypeAndBranch) \
|
2013-07-23 07:31:46 +00:00
|
|
|
V(InnerAllocatedObject) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(InstanceOf) \
|
2011-01-05 11:17:37 +00:00
|
|
|
V(InstanceOfKnownGlobal) \
|
2011-04-27 11:41:42 +00:00
|
|
|
V(InstructionGap) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(Integer32ToDouble) \
|
2011-04-15 07:58:22 +00:00
|
|
|
V(InvokeFunction) \
|
2011-05-11 11:53:43 +00:00
|
|
|
V(IsConstructCallAndBranch) \
|
2010-12-15 12:32:19 +00:00
|
|
|
V(IsObjectAndBranch) \
|
2011-11-17 13:57:55 +00:00
|
|
|
V(IsStringAndBranch) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(IsSmiAndBranch) \
|
2011-05-11 11:53:43 +00:00
|
|
|
V(IsUndetectableAndBranch) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(Label) \
|
|
|
|
V(LazyBailout) \
|
2011-01-17 08:11:03 +00:00
|
|
|
V(LoadContextSlot) \
|
2013-07-23 07:31:46 +00:00
|
|
|
V(LoadFieldByIndex) \
|
2011-02-03 13:10:28 +00:00
|
|
|
V(LoadFunctionPrototype) \
|
2011-04-01 11:54:04 +00:00
|
|
|
V(LoadGlobalCell) \
|
|
|
|
V(LoadGlobalGeneric) \
|
2012-11-02 09:18:53 +00:00
|
|
|
V(LoadKeyed) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(LoadKeyedGeneric) \
|
|
|
|
V(LoadNamedField) \
|
|
|
|
V(LoadNamedGeneric) \
|
2013-09-19 06:08:13 +00:00
|
|
|
V(LoadRoot) \
|
2012-08-28 14:20:50 +00:00
|
|
|
V(MapEnumLength) \
|
2013-04-11 13:27:06 +00:00
|
|
|
V(MathAbs) \
|
2014-02-19 13:51:49 +00:00
|
|
|
V(MathClz32) \
|
2012-11-26 13:12:35 +00:00
|
|
|
V(MathExp) \
|
2013-04-11 13:27:06 +00:00
|
|
|
V(MathFloor) \
|
|
|
|
V(MathLog) \
|
2012-08-06 14:28:27 +00:00
|
|
|
V(MathMinMax) \
|
2011-12-05 15:58:25 +00:00
|
|
|
V(MathPowHalf) \
|
2013-03-04 08:44:42 +00:00
|
|
|
V(MathRound) \
|
2013-04-11 13:27:06 +00:00
|
|
|
V(MathSqrt) \
|
2014-03-10 10:39:17 +00:00
|
|
|
V(ModByConstI) \
|
2014-03-07 10:36:28 +00:00
|
|
|
V(ModByPowerOf2I) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(ModI) \
|
|
|
|
V(MulI) \
|
|
|
|
V(NumberTagD) \
|
|
|
|
V(NumberTagI) \
|
2012-08-22 15:44:17 +00:00
|
|
|
V(NumberTagU) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(NumberUntagD) \
|
|
|
|
V(OsrEntry) \
|
|
|
|
V(Parameter) \
|
2010-12-08 14:32:40 +00:00
|
|
|
V(Power) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(PushArgument) \
|
|
|
|
V(RegExpLiteral) \
|
|
|
|
V(Return) \
|
2013-11-07 13:43:03 +00:00
|
|
|
V(SeqStringGetChar) \
|
2012-12-05 15:49:22 +00:00
|
|
|
V(SeqStringSetChar) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(ShiftI) \
|
|
|
|
V(SmiTag) \
|
|
|
|
V(SmiUntag) \
|
|
|
|
V(StackCheck) \
|
2013-08-27 11:55:08 +00:00
|
|
|
V(StoreCodeEntry) \
|
2011-02-03 13:10:28 +00:00
|
|
|
V(StoreContextSlot) \
|
2011-04-04 15:03:34 +00:00
|
|
|
V(StoreGlobalCell) \
|
2012-11-02 09:18:53 +00:00
|
|
|
V(StoreKeyed) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(StoreKeyedGeneric) \
|
|
|
|
V(StoreNamedField) \
|
|
|
|
V(StoreNamedGeneric) \
|
2011-04-15 06:39:36 +00:00
|
|
|
V(StringAdd) \
|
2011-01-19 20:05:22 +00:00
|
|
|
V(StringCharCodeAt) \
|
2011-03-14 15:36:00 +00:00
|
|
|
V(StringCharFromCode) \
|
2012-08-06 14:28:27 +00:00
|
|
|
V(StringCompareAndBranch) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(SubI) \
|
|
|
|
V(TaggedToI) \
|
2011-05-31 11:54:46 +00:00
|
|
|
V(ThisFunction) \
|
2011-03-21 12:25:31 +00:00
|
|
|
V(ToFastProperties) \
|
2011-10-19 12:10:18 +00:00
|
|
|
V(TransitionElementsKind) \
|
2013-02-04 12:01:59 +00:00
|
|
|
V(TrapAllocationMemento) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(Typeof) \
|
|
|
|
V(TypeofIsAndBranch) \
|
2013-07-23 07:31:46 +00:00
|
|
|
V(Uint32ToDouble) \
|
2010-12-07 11:31:57 +00:00
|
|
|
V(UnknownOSRValue) \
|
2013-07-23 07:31:46 +00:00
|
|
|
V(WrapReceiver)
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
|
|
|
|
virtual Opcode opcode() const V8_FINAL V8_OVERRIDE { \
|
|
|
|
return LInstruction::k##type; \
|
|
|
|
} \
|
|
|
|
virtual void CompileToNative(LCodeGen* generator) V8_FINAL V8_OVERRIDE; \
|
|
|
|
virtual const char* Mnemonic() const V8_FINAL V8_OVERRIDE { \
|
|
|
|
return mnemonic; \
|
|
|
|
} \
|
|
|
|
static L##type* cast(LInstruction* instr) { \
|
|
|
|
ASSERT(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,
|
|
|
|
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
|
|
|
|
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; }
|
|
|
|
|
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_; }
|
|
|
|
|
2012-04-26 12:43:00 +00:00
|
|
|
virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) { }
|
2011-01-26 08:03:48 +00:00
|
|
|
|
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
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
private:
|
2012-08-27 09:39:05 +00:00
|
|
|
// Iterator support.
|
|
|
|
friend class InputIterator;
|
|
|
|
virtual int InputCount() = 0;
|
|
|
|
virtual LOperand* InputAt(int i) = 0;
|
|
|
|
|
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);
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual bool HasResult() const V8_FINAL V8_OVERRIDE {
|
|
|
|
return R != 0 && result() != NULL;
|
|
|
|
}
|
2011-01-17 12:22:31 +00:00
|
|
|
void set_result(LOperand* operand) { results_[0] = operand; }
|
2013-07-29 11:57:42 +00:00
|
|
|
LOperand* result() const { 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.
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual int InputCount() V8_FINAL V8_OVERRIDE { return I; }
|
|
|
|
virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual int TempCount() V8_FINAL V8_OVERRIDE { return T; }
|
|
|
|
virtual LOperand* TempAt(int i) V8_FINAL V8_OVERRIDE { 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.
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual bool IsGap() const V8_FINAL V8_OVERRIDE { return true; }
|
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2011-04-27 11:41:42 +00:00
|
|
|
static LGap* cast(LInstruction* instr) {
|
|
|
|
ASSERT(instr->IsGap());
|
|
|
|
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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LInstructionGap V8_FINAL : public LGap {
|
2011-04-27 11:41:42 +00:00
|
|
|
public:
|
|
|
|
explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
|
2013-04-22 09:48:35 +00:00
|
|
|
return !IsRedundant();
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:41:42 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LGoto V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
|
|
|
virtual bool IsControl() const V8_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(); }
|
2014-04-30 09:50:58 +00:00
|
|
|
virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_OVERRIDE {
|
|
|
|
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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLazyBailout V8_FINAL : public LTemplateInstruction<0, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-11-08 14:16:34 +00:00
|
|
|
class LDummy V8_FINAL : public LTemplateInstruction<1, 0, 0> {
|
|
|
|
public:
|
|
|
|
explicit LDummy() { }
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LDummyUse V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LDeoptimize V8_FINAL : public LTemplateInstruction<0, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
|
|
|
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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLabel V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
|
|
|
|
return false;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Label, "label")
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LParameter V8_FINAL : public LTemplateInstruction<1, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
|
|
|
|
return false;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCallStub V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LUnknownOSRValue V8_FINAL : public LTemplateInstruction<1, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual bool HasInterestingComment(LCodeGen* gen) const V8_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) { }
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual bool IsControl() const V8_FINAL V8_OVERRIDE { 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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LWrapReceiver V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LApplyArguments V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LAccessArgumentsAt V8_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")
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LArgumentsLength V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LArgumentsElements V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LDebugBreak V8_FINAL : public LTemplateInstruction<0, 0, 0> {
|
2013-05-15 14:24:47 +00:00
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-03-07 10:36:28 +00:00
|
|
|
class LModByPowerOf2I V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
|
|
|
public:
|
|
|
|
LModByPowerOf2I(LOperand* dividend, int32_t divisor) {
|
|
|
|
inputs_[0] = dividend;
|
|
|
|
divisor_ = divisor;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* dividend() { return inputs_[0]; }
|
|
|
|
int32_t divisor() const { return divisor_; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ModByPowerOf2I, "mod-by-power-of-2-i")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Mod)
|
|
|
|
|
|
|
|
private:
|
|
|
|
int32_t divisor_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-03-10 10:39:17 +00:00
|
|
|
class LModByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
|
|
|
|
public:
|
|
|
|
LModByConstI(LOperand* dividend,
|
|
|
|
int32_t divisor,
|
|
|
|
LOperand* temp1,
|
|
|
|
LOperand* temp2) {
|
|
|
|
inputs_[0] = dividend;
|
|
|
|
divisor_ = divisor;
|
|
|
|
temps_[0] = temp1;
|
|
|
|
temps_[1] = temp2;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* dividend() { return inputs_[0]; }
|
|
|
|
int32_t divisor() const { return divisor_; }
|
|
|
|
LOperand* temp1() { return temps_[0]; }
|
|
|
|
LOperand* temp2() { return temps_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ModByConstI, "mod-by-const-i")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Mod)
|
|
|
|
|
|
|
|
private:
|
|
|
|
int32_t divisor_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LModI V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-03-07 10:36:28 +00:00
|
|
|
class LDivByPowerOf2I V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
|
|
|
public:
|
|
|
|
LDivByPowerOf2I(LOperand* dividend, int32_t divisor) {
|
|
|
|
inputs_[0] = dividend;
|
|
|
|
divisor_ = divisor;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* dividend() { return inputs_[0]; }
|
|
|
|
int32_t divisor() const { return divisor_; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DivByPowerOf2I, "div-by-power-of-2-i")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Div)
|
|
|
|
|
|
|
|
private:
|
|
|
|
int32_t divisor_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-03-10 10:39:17 +00:00
|
|
|
class LDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
|
|
|
|
public:
|
|
|
|
LDivByConstI(LOperand* dividend,
|
|
|
|
int32_t divisor,
|
|
|
|
LOperand* temp1,
|
|
|
|
LOperand* temp2) {
|
|
|
|
inputs_[0] = dividend;
|
|
|
|
divisor_ = divisor;
|
|
|
|
temps_[0] = temp1;
|
|
|
|
temps_[1] = temp2;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* dividend() { return inputs_[0]; }
|
|
|
|
int32_t divisor() const { return divisor_; }
|
|
|
|
LOperand* temp1() { return temps_[0]; }
|
|
|
|
LOperand* temp2() { return temps_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DivByConstI, "div-by-const-i")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(Div)
|
|
|
|
|
|
|
|
private:
|
|
|
|
int32_t divisor_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LDivI V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-03-07 10:36:28 +00:00
|
|
|
class LFlooringDivByPowerOf2I V8_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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-03-20 13:10:23 +00:00
|
|
|
class LFlooringDivByConstI V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-04-01 11:42:42 +00:00
|
|
|
class LFlooringDivI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
|
|
|
|
public:
|
|
|
|
LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
|
|
|
|
inputs_[0] = dividend;
|
|
|
|
inputs_[1] = divisor;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* 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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LMulI V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCompareNumericAndBranch V8_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
|
|
|
|
2011-01-17 12:22:31 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream);
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LMathFloor V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-11-08 10:58:51 +00:00
|
|
|
class LMathRound V8_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
|
|
|
|
2011-07-04 14:13:08 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
2013-04-11 13:27:06 +00:00
|
|
|
LOperand* temp() { return temps_[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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LMathAbs V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LMathLog V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-02-19 13:51:49 +00:00
|
|
|
class LMathClz32 V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
|
|
|
public:
|
|
|
|
explicit LMathClz32(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LMathExp V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LMathSqrt V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-11-08 10:58:51 +00:00
|
|
|
class LMathPowHalf V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCmpObjectEqAndBranch V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCmpHoleAndBranch V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-11-12 11:53:13 +00:00
|
|
|
class LCompareMinusZeroAndBranch V8_FINAL : public LControlInstruction<1, 1> {
|
|
|
|
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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LIsObjectAndBranch V8_FINAL : public LControlInstruction<1, 1> {
|
2010-12-15 12:32:19 +00:00
|
|
|
public:
|
2011-06-28 14:21:55 +00:00
|
|
|
LIsObjectAndBranch(LOperand* value, LOperand* temp) {
|
2011-01-17 12:22:31 +00:00
|
|
|
inputs_[0] = value;
|
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2010-12-15 12:32:19 +00:00
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2010-12-15 12:32:19 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-15 12:32:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LIsStringAndBranch V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2011-11-17 13:57:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LIsSmiAndBranch V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LIsUndetectableAndBranch V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2011-05-11 11:53:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LStringCompareAndBranch V8_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)
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2011-11-17 13:57:55 +00:00
|
|
|
|
|
|
|
Token::Value op() const { return hydrogen()->token(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LHasInstanceTypeAndBranch V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LGetCachedArrayIndex V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LHasCachedArrayIndexAndBranch V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LIsConstructCallAndBranch V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LClassOfTestAndBranch V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-09-23 18:57:32 +00:00
|
|
|
class LCmpT V8_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
|
|
|
|
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(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LInstanceOf V8_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
|
|
|
|
2011-02-10 09:00:50 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LInstanceOfKnownGlobal V8_FINAL : public LTemplateInstruction<1, 2, 1> {
|
2011-01-05 11:17:37 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
LInstanceOfKnownGlobal(LOperand* context, LOperand* value, LOperand* temp) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = value;
|
2011-01-17 12:22:31 +00:00
|
|
|
temps_[0] = temp;
|
|
|
|
}
|
2011-01-05 11:17:37 +00:00
|
|
|
|
2013-11-08 10:58:51 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[1]; }
|
|
|
|
LOperand* temp() { return temps_[0]; }
|
|
|
|
|
2011-01-05 11:17:37 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
|
|
|
|
"instance-of-known-global")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
|
|
|
|
|
|
|
|
Handle<JSFunction> function() const { return hydrogen()->function(); }
|
2012-04-26 12:43:00 +00:00
|
|
|
LEnvironment* GetDeferredLazyDeoptimizationEnvironment() {
|
|
|
|
return lazy_deopt_env_;
|
|
|
|
}
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void SetDeferredLazyDeoptimizationEnvironment(
|
|
|
|
LEnvironment* env) V8_OVERRIDE {
|
2012-04-26 12:43:00 +00:00
|
|
|
lazy_deopt_env_ = env;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
LEnvironment* lazy_deopt_env_;
|
2011-01-05 11:17:37 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LBoundsCheck V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LBitI V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LShiftI V8_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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LSubI V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LConstantI V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LConstantS V8_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()); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LConstantD V8_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
|
|
|
|
2011-02-08 10:45:21 +00:00
|
|
|
double value() const { return hydrogen()->DoubleValue(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LConstantE V8_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();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LConstantT V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LBranch V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCmpMapAndBranch V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LMapEnumLength V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LDateField V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-11-07 13:43:03 +00:00
|
|
|
class LSeqStringGetChar V8_FINAL : public LTemplateInstruction<1, 2, 0> {
|
|
|
|
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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-11-19 16:41:07 +00:00
|
|
|
class LSeqStringSetChar V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LAddI V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LMathMinMax V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LPower V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LArithmeticD V8_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_; }
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual Opcode opcode() const V8_OVERRIDE {
|
|
|
|
return LInstruction::kArithmeticD;
|
|
|
|
}
|
|
|
|
virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
|
|
|
|
virtual const char* Mnemonic() const V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
Token::Value op_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LArithmeticT V8_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]; }
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual Opcode opcode() const V8_OVERRIDE {
|
|
|
|
return LInstruction::kArithmeticT;
|
|
|
|
}
|
|
|
|
virtual void CompileToNative(LCodeGen* generator) V8_OVERRIDE;
|
|
|
|
virtual const char* Mnemonic() const V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
Token::Value op() const { return op_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Token::Value op_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LReturn V8_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() {
|
|
|
|
ASSERT(has_constant_parameter_count());
|
|
|
|
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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLoadNamedField V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLoadNamedGeneric V8_FINAL : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-02-10 09:00:50 +00:00
|
|
|
LLoadNamedGeneric(LOperand* context, LOperand* object) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = object;
|
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]; }
|
|
|
|
|
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(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLoadFunctionPrototype V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-09-19 06:08:13 +00:00
|
|
|
class LLoadRoot V8_FINAL : public LTemplateInstruction<1, 0, 0> {
|
|
|
|
public:
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
|
|
|
|
|
|
|
|
Heap::RootListIndex index() const { return hydrogen()->index(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLoadKeyed V8_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();
|
|
|
|
}
|
|
|
|
bool is_external() const {
|
|
|
|
return hydrogen()->is_external();
|
2011-07-19 13:04:00 +00:00
|
|
|
}
|
2014-01-16 17:08:45 +00:00
|
|
|
bool is_fixed_typed_array() const {
|
|
|
|
return hydrogen()->is_fixed_typed_array();
|
|
|
|
}
|
|
|
|
bool is_typed_elements() const {
|
|
|
|
return is_external() || 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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_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() &&
|
2014-01-24 16:01:15 +00:00
|
|
|
(elements_kind == EXTERNAL_INT8_ELEMENTS ||
|
|
|
|
elements_kind == EXTERNAL_UINT8_ELEMENTS ||
|
|
|
|
elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS ||
|
2014-01-16 17:08:45 +00:00
|
|
|
elements_kind == UINT8_ELEMENTS ||
|
|
|
|
elements_kind == INT8_ELEMENTS ||
|
|
|
|
elements_kind == UINT8_CLAMPED_ELEMENTS);
|
2012-07-20 11:00:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLoadKeyedGeneric V8_FINAL : public LTemplateInstruction<1, 3, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-02-10 09:00:50 +00:00
|
|
|
LLoadKeyedGeneric(LOperand* context, LOperand* obj, LOperand* key) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = obj;
|
|
|
|
inputs_[2] = key;
|
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]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLoadGlobalCell V8_FINAL : public LTemplateInstruction<1, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-04-01 11:54:04 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLoadGlobalGeneric V8_FINAL : public LTemplateInstruction<1, 2, 0> {
|
2011-04-01 11:54:04 +00:00
|
|
|
public:
|
|
|
|
LLoadGlobalGeneric(LOperand* context, LOperand* global_object) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = global_object;
|
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
LOperand* global_object() { return inputs_[1]; }
|
|
|
|
|
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(); }
|
|
|
|
bool for_typeof() const { return hydrogen()->for_typeof(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LStoreGlobalCell V8_FINAL : public LTemplateInstruction<0, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-12-20 10:57:12 +00:00
|
|
|
explicit LStoreGlobalCell(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-04-04 15:03:34 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLoadContextSlot V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2011-01-17 08:11:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LStoreContextSlot V8_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(); }
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2011-02-03 13:10:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LPushArgument V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LDrop V8_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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-27 11:55:08 +00:00
|
|
|
class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
|
|
|
|
public:
|
|
|
|
LStoreCodeEntry(LOperand* function, LOperand* code_object) {
|
|
|
|
inputs_[0] = function;
|
|
|
|
temps_[0] = code_object;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* function() { return inputs_[0]; }
|
|
|
|
LOperand* code_object() { return temps_[0]; }
|
|
|
|
|
|
|
|
virtual void PrintDataTo(StringStream* stream);
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-12-02 11:24:31 +00:00
|
|
|
class LInnerAllocatedObject V8_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
|
|
|
|
|
|
|
virtual void PrintDataTo(StringStream* stream);
|
|
|
|
|
2013-12-02 11:24:31 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
|
2013-03-13 11:05:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LThisFunction V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LContext V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LDeclareGlobals V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
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
|
|
|
class LCallJSFunction V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +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
|
|
|
class LCallWithDescriptor V8_FINAL : public LTemplateResultInstruction<1> {
|
2011-04-15 07:58:22 +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
|
|
|
LCallWithDescriptor(const CallInterfaceDescriptor* descriptor,
|
|
|
|
ZoneList<LOperand*>& operands,
|
|
|
|
Zone* zone)
|
2014-01-19 12:24:25 +00:00
|
|
|
: inputs_(descriptor->environment_length() + 1, zone) {
|
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
|
|
|
ASSERT(descriptor->environment_length() + 1 == operands.length());
|
|
|
|
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
|
|
|
|
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")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_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.
|
|
|
|
virtual int InputCount() V8_FINAL V8_OVERRIDE { return inputs_.length(); }
|
|
|
|
virtual LOperand* InputAt(int i) V8_FINAL V8_OVERRIDE { return inputs_[i]; }
|
2010-12-07 11:31:57 +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
|
|
|
virtual int TempCount() V8_FINAL V8_OVERRIDE { return 0; }
|
|
|
|
virtual LOperand* TempAt(int i) V8_FINAL V8_OVERRIDE { return NULL; }
|
2010-12-07 11:31:57 +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
|
|
|
class LInvokeFunction V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
int arity() const { return hydrogen()->argument_count() - 1; }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCallFunction V8_FINAL : public LTemplateInstruction<1, 2, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-11-08 14:39:37 +00:00
|
|
|
explicit LCallFunction(LOperand* context, LOperand* function) {
|
2011-02-10 09:00:50 +00:00
|
|
|
inputs_[0] = context;
|
2011-11-08 14:39:37 +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]; }
|
|
|
|
LOperand* function() { return inputs_[1]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(CallFunction)
|
|
|
|
|
2011-11-08 14:39:37 +00:00
|
|
|
int arity() const { return hydrogen()->argument_count() - 1; }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCallNew V8_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)
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
int arity() const { return hydrogen()->argument_count() - 1; }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCallNewArray V8_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)
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2013-03-01 16:06:34 +00:00
|
|
|
|
|
|
|
int arity() const { return hydrogen()->argument_count() - 1; }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCallRuntime V8_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)
|
|
|
|
|
2014-04-30 09:50:58 +00:00
|
|
|
virtual bool ClobbersDoubleRegisters(Isolate* isolate) const V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LInteger32ToDouble V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 1> {
|
2012-08-22 15:44:17 +00:00
|
|
|
public:
|
|
|
|
explicit LUint32ToDouble(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]; }
|
|
|
|
|
2012-08-22 15:44:17 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-03-04 12:45:00 +00:00
|
|
|
class LNumberTagI V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-03-04 12:45:00 +00:00
|
|
|
class LNumberTagU V8_FINAL : public LTemplateInstruction<1, 1, 2> {
|
2012-08-22 15:44:17 +00:00
|
|
|
public:
|
2014-03-04 12:45:00 +00:00
|
|
|
LNumberTagU(LOperand* value, LOperand* temp1, LOperand* temp2) {
|
2012-08-22 15:44:17 +00:00
|
|
|
inputs_[0] = value;
|
2014-03-04 12:45:00 +00:00
|
|
|
temps_[0] = temp1;
|
|
|
|
temps_[1] = temp2;
|
2012-08-22 15:44:17 +00:00
|
|
|
}
|
|
|
|
|
2012-09-14 11:55:49 +00:00
|
|
|
LOperand* value() { return inputs_[0]; }
|
2014-03-04 12:45:00 +00:00
|
|
|
LOperand* temp1() { return temps_[0]; }
|
|
|
|
LOperand* temp2() { return temps_[1]; }
|
2012-09-14 11:55:49 +00:00
|
|
|
|
2012-08-22 15:44:17 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LNumberTagD V8_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.
|
2013-08-20 11:10:24 +00:00
|
|
|
class LDoubleToI V8_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(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LDoubleToSmi V8_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.
|
2013-08-20 11:10:24 +00:00
|
|
|
class LTaggedToI V8_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(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LSmiTag V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LNumberUntagD V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LSmiUntag V8_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_;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-05-20 13:03:25 +00:00
|
|
|
class LStoreNamedField V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LStoreNamedGeneric V8_FINAL : public LTemplateInstruction<0, 3, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-02-10 09:00:50 +00:00
|
|
|
LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = object;
|
|
|
|
inputs_[2] = value;
|
|
|
|
}
|
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]; }
|
|
|
|
|
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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2011-02-10 09:00:50 +00:00
|
|
|
Handle<Object> name() const { return hydrogen()->name(); }
|
2014-03-11 14:41:22 +00:00
|
|
|
StrictMode strict_mode() { return hydrogen()->strict_mode(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LStoreKeyed V8_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
|
|
|
|
2012-11-02 09:18:53 +00:00
|
|
|
bool is_external() const { return hydrogen()->is_external(); }
|
2014-01-16 17:08:45 +00:00
|
|
|
bool is_fixed_typed_array() const {
|
|
|
|
return hydrogen()->is_fixed_typed_array();
|
|
|
|
}
|
|
|
|
bool is_typed_elements() const {
|
|
|
|
return is_external() || 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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LStoreKeyedGeneric V8_FINAL : public LTemplateInstruction<0, 4, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-02-10 09:00:50 +00:00
|
|
|
LStoreKeyedGeneric(LOperand* context,
|
|
|
|
LOperand* object,
|
|
|
|
LOperand* key,
|
|
|
|
LOperand* value) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = object;
|
|
|
|
inputs_[2] = key;
|
|
|
|
inputs_[3] = value;
|
|
|
|
}
|
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]; }
|
|
|
|
|
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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2011-02-23 11:19:50 +00:00
|
|
|
|
2014-03-11 14:41:22 +00:00
|
|
|
StrictMode strict_mode() { return hydrogen()->strict_mode(); }
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LTransitionElementsKind V8_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)
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-05-09 08:28:25 +00:00
|
|
|
class LArrayShift V8_FINAL : public LTemplateInstruction<1, 2, 0> {
|
|
|
|
public:
|
|
|
|
LArrayShift(LOperand* context, LOperand* object) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
inputs_[1] = object;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* context() const { return inputs_[0]; }
|
|
|
|
LOperand* object() const { return inputs_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ArrayShift, "array-shift")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(ArrayShift)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LTrapAllocationMemento V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LStringAdd V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LStringCharCodeAt V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LStringCharFromCode V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-28 14:16:57 +00:00
|
|
|
class LCheckValue V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCheckInstanceType V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCheckMaps V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCheckSmi V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LClampDToUint8 V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LClampIToUint8 V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LClampTToUint8 V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCheckNonSmi V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-03-07 14:58:41 +00:00
|
|
|
class LDoubleBits V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
|
|
|
public:
|
|
|
|
explicit LDoubleBits(LOperand* value) {
|
|
|
|
inputs_[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* value() { return inputs_[0]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(DoubleBits)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class LConstructDouble V8_FINAL : public LTemplateInstruction<1, 2, 0> {
|
|
|
|
public:
|
|
|
|
LConstructDouble(LOperand* hi, LOperand* lo) {
|
|
|
|
inputs_[0] = hi;
|
|
|
|
inputs_[1] = lo;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* hi() { return inputs_[0]; }
|
|
|
|
LOperand* lo() { return inputs_[1]; }
|
|
|
|
|
|
|
|
DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LAllocate V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LRegExpLiteral V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LFunctionLiteral V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2011-07-04 14:13:08 +00:00
|
|
|
explicit LFunctionLiteral(LOperand* context) {
|
|
|
|
inputs_[0] = context;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOperand* context() { return inputs_[0]; }
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
|
|
|
|
DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LToFastProperties V8_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)
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LTypeof V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LTypeofIsAndBranch V8_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
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
|
2010-12-07 11:31:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LOsrEntry V8_FINAL : public LTemplateInstruction<0, 0, 0> {
|
2010-12-07 11:31:57 +00:00
|
|
|
public:
|
2013-08-20 11:10:24 +00:00
|
|
|
virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE {
|
|
|
|
return false;
|
|
|
|
}
|
2010-12-07 11:31:57 +00:00
|
|
|
DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LStackCheck V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LForInPrepareMap V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LForInCacheArray V8_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();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LCheckMapValue V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-08-20 11:10:24 +00:00
|
|
|
class LLoadFieldByIndex V8_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")
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-12-07 11:31:57 +00:00
|
|
|
class LChunkBuilder;
|
2013-08-20 11:10:24 +00:00
|
|
|
class LPlatformChunk V8_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
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-01-07 14:36:26 +00:00
|
|
|
class LChunkBuilder V8_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-01-07 14:36:26 +00:00
|
|
|
: LChunkBuilderBase(graph->zone()),
|
|
|
|
chunk_(NULL),
|
2011-03-07 11:52:36 +00:00
|
|
|
info_(info),
|
2010-12-07 11:31:57 +00:00
|
|
|
graph_(graph),
|
|
|
|
status_(UNUSED),
|
|
|
|
current_instruction_(NULL),
|
|
|
|
current_block_(NULL),
|
|
|
|
next_block_(NULL),
|
2014-03-12 09:59:36 +00:00
|
|
|
allocator_(allocator) { }
|
2010-12-07 11:31:57 +00:00
|
|
|
|
2014-04-30 09:50:58 +00:00
|
|
|
Isolate* isolate() const { return graph_->isolate(); }
|
|
|
|
|
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
|
|
|
|
2013-10-02 11:43:41 +00:00
|
|
|
LInstruction* CheckElideControlInstruction(HControlInstruction* instr);
|
|
|
|
|
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);
|
|
|
|
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:
|
|
|
|
enum Status {
|
|
|
|
UNUSED,
|
|
|
|
BUILDING,
|
|
|
|
DONE,
|
|
|
|
ABORTED
|
|
|
|
};
|
|
|
|
|
2012-07-12 15:29:14 +00:00
|
|
|
LPlatformChunk* chunk() const { return chunk_; }
|
2011-03-07 11:52:36 +00:00
|
|
|
CompilationInfo* info() const { return info_; }
|
2010-12-07 11:31:57 +00:00
|
|
|
HGraph* graph() const { return graph_; }
|
|
|
|
|
|
|
|
bool is_unused() const { return status_ == UNUSED; }
|
|
|
|
bool is_building() const { return status_ == BUILDING; }
|
|
|
|
bool is_done() const { return status_ == DONE; }
|
|
|
|
bool is_aborted() const { return status_ == ABORTED; }
|
|
|
|
|
2013-08-02 09:53:11 +00:00
|
|
|
void Abort(BailoutReason reason);
|
2010-12-07 11:31:57 +00:00
|
|
|
|
|
|
|
// 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.
|
2014-01-07 14:36:26 +00:00
|
|
|
virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) V8_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);
|
|
|
|
|
2012-07-12 15:29:14 +00:00
|
|
|
LPlatformChunk* chunk_;
|
2011-03-07 11:52:36 +00:00
|
|
|
CompilationInfo* info_;
|
2010-12-07 11:31:57 +00:00
|
|
|
HGraph* const graph_;
|
|
|
|
Status status_;
|
|
|
|
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_
|