Index: src/code-stubs.h |
diff --git a/src/code-stubs.h b/src/code-stubs.h |
index 8f1b686743317a39f95b764933a901de4b788214..cd14047abd6cdffd84c9b89de4c5b2b931a43129 100644 |
--- a/src/code-stubs.h |
+++ b/src/code-stubs.h |
@@ -90,13 +90,15 @@ namespace internal { |
V(TransitionElementsKind) \ |
V(StoreArrayLiteralElement) \ |
V(StubFailureTrampoline) \ |
+ V(StubFailureTailCallTrampoline) \ |
V(ArrayConstructor) \ |
V(InternalArrayConstructor) \ |
V(ProfileEntryHook) \ |
V(StoreGlobal) \ |
/* IC Handler stubs */ \ |
V(LoadField) \ |
- V(KeyedLoadField) |
+ V(KeyedLoadField) \ |
+ V(KeyedArrayCall) |
// List of code stubs only used on ARM platforms. |
#if V8_TARGET_ARCH_ARM |
@@ -170,6 +172,7 @@ class CodeStub BASE_EMBEDDED { |
virtual bool IsPregenerated(Isolate* isolate) { return false; } |
static void GenerateStubsAheadOfTime(Isolate* isolate); |
+ static void GenerateStubsRequiringBuiltinsAheadOfTime(Isolate* isolate); |
static void GenerateFPStubs(Isolate* isolate); |
// Some stubs put untagged junk on the stack that cannot be scanned by the |
@@ -279,6 +282,9 @@ class PlatformCodeStub : public CodeStub { |
enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; |
enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; |
+enum ContinuationType { NORMAL_CONTINUATION, TAIL_CALL_CONTINUATION }; |
+ |
+ |
struct CodeStubInterfaceDescriptor { |
CodeStubInterfaceDescriptor(); |
int register_param_count_; |
@@ -287,18 +293,23 @@ struct CodeStubInterfaceDescriptor { |
// if hint_stack_parameter_count_ > 0, the code stub can optimize the |
// return sequence. Default value is -1, which means it is ignored. |
int hint_stack_parameter_count_; |
+ ContinuationType continuation_type_; |
StubFunctionMode function_mode_; |
Register* register_params_; |
Address deoptimization_handler_; |
HandlerArgumentsMode handler_arguments_mode_; |
+ bool initialized() const { return register_param_count_ >= 0; } |
+ |
+ bool HasTailCallContinuation() const { |
+ return continuation_type_ == TAIL_CALL_CONTINUATION; |
+ } |
+ |
int environment_length() const { |
return register_param_count_; |
} |
- bool initialized() const { return register_param_count_ >= 0; } |
- |
void SetMissHandler(ExternalReference handler) { |
miss_handler_ = handler; |
has_miss_handler_ = true; |
@@ -876,6 +887,11 @@ class HandlerStub: public HICStub { |
public: |
virtual Code::Kind GetCodeKind() const { return Code::HANDLER; } |
virtual int GetStubFlags() { return kind(); } |
+ |
+ protected: |
+ HandlerStub() : HICStub() { } |
+ virtual int NotMissMinorKey() { return bit_field_; } |
+ int bit_field_; |
}; |
@@ -937,9 +953,6 @@ class LoadFieldStub: public HandlerStub { |
class IndexBits: public BitField<int, 5, 11> {}; |
class UnboxedDoubleBits: public BitField<bool, 16, 1> {}; |
virtual CodeStub::Major MajorKey() { return LoadField; } |
- virtual int NotMissMinorKey() { return bit_field_; } |
- |
- int bit_field_; |
}; |
@@ -1018,6 +1031,52 @@ class KeyedLoadFieldStub: public LoadFieldStub { |
}; |
+class KeyedArrayCallStub: public HICStub { |
+ public: |
+ KeyedArrayCallStub(bool holey, int argc) : HICStub(), argc_(argc) { |
+ bit_field_ = KindBits::encode(Code::KEYED_CALL_IC) |
+ | HoleyBits::encode(holey); |
+ } |
+ |
+ virtual Code::Kind kind() const { |
+ return KindBits::decode(bit_field_); |
+ } |
+ |
+ virtual Code::ExtraICState GetExtraICState() { return bit_field_; } |
+ |
+ ElementsKind elements_kind() { |
+ return HoleyBits::decode(bit_field_) ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; |
+ } |
+ |
+ int argc() { return argc_; } |
+ virtual int GetStubFlags() { return argc(); } |
+ |
+ static bool IsHoley(Handle<Code> code) { |
+ Code::ExtraICState state = code->extra_ic_state(); |
+ return HoleyBits::decode(state); |
+ } |
+ |
+ virtual void InitializeInterfaceDescriptor( |
+ Isolate* isolate, |
+ CodeStubInterfaceDescriptor* descriptor); |
+ |
+ virtual Handle<Code> GenerateCode(Isolate* isolate); |
+ |
+ private: |
+ virtual int NotMissMinorKey() { |
+ return GetExtraICState() | ArgcBits::encode(argc_); |
+ } |
+ |
+ STATIC_ASSERT(KindBits::kSize == 4); |
+ class HoleyBits: public BitField<bool, 4, 1> {}; |
+ STATIC_ASSERT(Code::kArgumentsBits <= kStubMinorKeyBits - 5); |
+ class ArgcBits: public BitField<int, 5, Code::kArgumentsBits> {}; |
+ virtual CodeStub::Major MajorKey() { return KeyedArrayCall; } |
+ int bit_field_; |
+ int argc_; |
+}; |
+ |
+ |
class BinaryOpStub: public HydrogenCodeStub { |
public: |
BinaryOpStub(Token::Value op, OverwriteMode mode) |
@@ -2399,6 +2458,27 @@ class StubFailureTrampolineStub : public PlatformCodeStub { |
}; |
+class StubFailureTailCallTrampolineStub : public PlatformCodeStub { |
+ public: |
+ StubFailureTailCallTrampolineStub() : fp_registers_(CanUseFPRegisters()) {} |
+ |
+ virtual bool IsPregenerated(Isolate* isolate) V8_OVERRIDE { return true; } |
+ |
+ static void GenerateAheadOfTime(Isolate* isolate); |
+ |
+ private: |
+ class FPRegisters: public BitField<bool, 0, 1> {}; |
+ Major MajorKey() { return StubFailureTailCallTrampoline; } |
+ int MinorKey() { return FPRegisters::encode(fp_registers_); } |
+ |
+ void Generate(MacroAssembler* masm); |
+ |
+ bool fp_registers_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(StubFailureTailCallTrampolineStub); |
+}; |
+ |
+ |
class ProfileEntryHookStub : public PlatformCodeStub { |
public: |
explicit ProfileEntryHookStub() {} |