| Index: src/code-stubs.h
|
| diff --git a/src/code-stubs.h b/src/code-stubs.h
|
| index 8f1b686743317a39f95b764933a901de4b788214..e9c3e62c3e7a6aa338dcc450e448deccd84531f6 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,50 @@ class KeyedLoadFieldStub: public LoadFieldStub {
|
| };
|
|
|
|
|
| +class KeyedArrayCallStub: public HICStub {
|
| + public:
|
| + KeyedArrayCallStub(bool holey, int argc) : HICStub(), argc_(argc) {
|
| + bit_field_ = ContextualBits::encode(false) | HoleyBits::encode(holey);
|
| + }
|
| +
|
| + virtual Code::Kind kind() const { return Code::KEYED_CALL_IC; }
|
| + 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_);
|
| + }
|
| +
|
| + class ContextualBits: public BitField<bool, 0, 1> {};
|
| + STATIC_ASSERT(CallICBase::Contextual::kShift == ContextualBits::kShift);
|
| + STATIC_ASSERT(CallICBase::Contextual::kSize == ContextualBits::kSize);
|
| + class HoleyBits: public BitField<bool, 1, 1> {};
|
| + STATIC_ASSERT(Code::kArgumentsBits <= kStubMinorKeyBits - 2);
|
| + class ArgcBits: public BitField<int, 2, 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 +2456,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() {}
|
|
|