Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 8448e55..21e2135 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -8,6 +8,7 @@
#include "src/allocation.h"
#include "src/assembler.h"
#include "src/codegen.h"
+#include "src/compiler/code-stub-assembler.h"
#include "src/globals.h"
#include "src/ic/ic-state.h"
#include "src/interface-descriptors.h"
@@ -24,35 +25,44 @@
V(ArrayConstructor) \
V(BinaryOpICWithAllocationSite) \
V(CallApiFunction) \
+ V(CallApiAccessor) \
V(CallApiGetter) \
V(CallConstruct) \
- V(CallFunction) \
V(CallIC) \
- V(CallIC_Array) \
V(CEntry) \
V(CompareIC) \
V(DoubleToI) \
V(FunctionPrototype) \
- V(Instanceof) \
+ V(InstanceOf) \
V(InternalArrayConstructor) \
V(JSEntry) \
V(KeyedLoadICTrampoline) \
V(LoadICTrampoline) \
+ V(CallICTrampoline) \
V(LoadIndexedInterceptor) \
V(LoadIndexedString) \
V(MathPow) \
V(ProfileEntryHook) \
V(RecordWrite) \
+ V(RestParamAccess) \
V(RegExpExec) \
- V(StoreArrayLiteralElement) \
V(StoreBufferOverflow) \
V(StoreElement) \
V(StringCompare) \
V(StubFailureTrampoline) \
V(SubString) \
V(ToNumber) \
+ V(ToLength) \
+ V(ToString) \
+ V(ToObject) \
+ V(VectorStoreICTrampoline) \
+ V(VectorKeyedStoreICTrampoline) \
+ V(VectorStoreIC) \
+ V(VectorKeyedStoreIC) \
/* HydrogenCodeStubs */ \
V(AllocateHeapNumber) \
+ V(AllocateMutableHeapNumber) \
+ V(AllocateInNewSpace) \
V(ArrayNArgumentsConstructor) \
V(ArrayNoArgumentConstructor) \
V(ArraySingleArgumentConstructor) \
@@ -60,37 +70,45 @@
V(BinaryOpWithAllocationSite) \
V(CompareNilIC) \
V(CreateAllocationSite) \
+ V(CreateWeakCell) \
V(ElementsTransitionAndStore) \
+ V(FastCloneRegExp) \
V(FastCloneShallowArray) \
V(FastCloneShallowObject) \
V(FastNewClosure) \
V(FastNewContext) \
+ V(GrowArrayElements) \
V(InternalArrayNArgumentsConstructor) \
V(InternalArrayNoArgumentConstructor) \
V(InternalArraySingleArgumentConstructor) \
V(KeyedLoadGeneric) \
+ V(LoadGlobalViaContext) \
V(LoadScriptContextField) \
V(LoadDictionaryElement) \
- V(LoadFastElement) \
- V(MegamorphicLoad) \
V(NameDictionaryLookup) \
V(NumberToString) \
+ V(Typeof) \
V(RegExpConstructResult) \
V(StoreFastElement) \
+ V(StoreGlobalViaContext) \
V(StoreScriptContextField) \
V(StringAdd) \
V(ToBoolean) \
V(TransitionElementsKind) \
- V(VectorKeyedLoad) \
- V(VectorLoad) \
+ V(KeyedLoadIC) \
+ V(LoadIC) \
+ /* TurboFanCodeStubs */ \
+ V(StringLength) \
/* IC Handler stubs */ \
+ V(ArrayBufferViewLoadField) \
V(LoadConstant) \
+ V(LoadFastElement) \
V(LoadField) \
V(KeyedLoadSloppyArguments) \
+ V(KeyedStoreSloppyArguments) \
V(StoreField) \
V(StoreGlobal) \
- V(StoreTransition) \
- V(StringLength)
+ V(StoreTransition)
// List of code stubs only used on ARM 32 bits platforms.
#if V8_TARGET_ARCH_ARM
@@ -111,6 +129,16 @@
#define CODE_STUB_LIST_ARM64(V)
#endif
+// List of code stubs only used on PPC platforms.
+#ifdef V8_TARGET_ARCH_PPC
+#define CODE_STUB_LIST_PPC(V) \
+ V(DirectCEntry) \
+ V(StoreRegistersState) \
+ V(RestoreRegistersState)
+#else
+#define CODE_STUB_LIST_PPC(V)
+#endif
+
// List of code stubs only used on MIPS platforms.
#if V8_TARGET_ARCH_MIPS
#define CODE_STUB_LIST_MIPS(V) \
@@ -127,12 +155,15 @@
#endif
// Combined list of code stubs.
-#define CODE_STUB_LIST(V) \
- CODE_STUB_LIST_ALL_PLATFORMS(V) \
- CODE_STUB_LIST_ARM(V) \
- CODE_STUB_LIST_ARM64(V) \
+#define CODE_STUB_LIST(V) \
+ CODE_STUB_LIST_ALL_PLATFORMS(V) \
+ CODE_STUB_LIST_ARM(V) \
+ CODE_STUB_LIST_ARM64(V) \
+ CODE_STUB_LIST_PPC(V) \
CODE_STUB_LIST_MIPS(V)
+static const int kHasReturnedMinusZeroSentinel = 1;
+
// Stub is base classes of all stubs.
class CodeStub BASE_EMBEDDED {
public:
@@ -166,7 +197,7 @@
static uint32_t NoCacheKey() { return MajorKeyBits::encode(NoCache); }
- static const char* MajorName(Major major_key, bool allow_unknown_keys);
+ static const char* MajorName(Major major_key);
explicit CodeStub(Isolate* isolate) : minor_key_(0), isolate_(isolate) {}
virtual ~CodeStub() {}
@@ -185,7 +216,11 @@
// Lookup the code in the (possibly custom) cache.
bool FindCodeInCache(Code** code_out);
- virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() = 0;
+ virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() const = 0;
+
+ virtual int GetStackParameterCount() const {
+ return GetCallInterfaceDescriptor().GetStackParameterCount();
+ }
virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) {}
@@ -198,11 +233,12 @@
virtual Major MajorKey() const = 0;
uint32_t MinorKey() const { return minor_key_; }
+ // BinaryOpStub needs to override this.
+ virtual Code::Kind GetCodeKind() const;
+
virtual InlineCacheState GetICState() const { return UNINITIALIZED; }
virtual ExtraICState GetExtraICState() const { return kNoExtraICState; }
- virtual Code::StubType GetStubType() {
- return Code::NORMAL;
- }
+ virtual Code::StubType GetStubType() const { return Code::NORMAL; }
friend std::ostream& operator<<(std::ostream& os, const CodeStub& s) {
s.PrintName(os);
@@ -246,9 +282,6 @@
// registering stub in the stub cache.
virtual void Activate(Code* code) { }
- // BinaryOpStub needs to override this.
- virtual Code::Kind GetCodeKind() const;
-
// Add the code to a specialized cache, specific to an individual
// stub type. Please note, this method must add the code object to a
// roots object, otherwise we will remove the code during GC.
@@ -291,50 +324,55 @@
#define DEFINE_CODE_STUB(NAME, SUPER) \
protected: \
- inline Major MajorKey() const OVERRIDE { return NAME; }; \
+ inline Major MajorKey() const override { return NAME; }; \
DEFINE_CODE_STUB_BASE(NAME##Stub, SUPER)
#define DEFINE_PLATFORM_CODE_STUB(NAME, SUPER) \
private: \
- void Generate(MacroAssembler* masm) OVERRIDE; \
+ void Generate(MacroAssembler* masm) override; \
DEFINE_CODE_STUB(NAME, SUPER)
#define DEFINE_HYDROGEN_CODE_STUB(NAME, SUPER) \
public: \
- void InitializeDescriptor(CodeStubDescriptor* descriptor) OVERRIDE; \
- Handle<Code> GenerateCode() OVERRIDE; \
+ void InitializeDescriptor(CodeStubDescriptor* descriptor) override; \
+ Handle<Code> GenerateCode() override; \
+ DEFINE_CODE_STUB(NAME, SUPER)
+
+#define DEFINE_TURBOFAN_CODE_STUB(NAME, SUPER) \
+ public: \
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
+ return DESC##Descriptor(isolate()); \
+ }; \
DEFINE_CODE_STUB(NAME, SUPER)
#define DEFINE_HANDLER_CODE_STUB(NAME, SUPER) \
public: \
- Handle<Code> GenerateCode() OVERRIDE; \
+ Handle<Code> GenerateCode() override; \
DEFINE_CODE_STUB(NAME, SUPER)
-#define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME) \
- public: \
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { \
- return NAME##Descriptor(isolate()); \
+#define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME) \
+ public: \
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
+ return NAME##Descriptor(isolate()); \
}
// There are some code stubs we just can't describe right now with a
// CallInterfaceDescriptor. Isolate behavior for those cases with this macro.
// An attempt to retrieve a descriptor will fail.
-#define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR() \
- public: \
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { \
- UNREACHABLE(); \
- return CallInterfaceDescriptor(); \
+#define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR() \
+ public: \
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
+ UNREACHABLE(); \
+ return CallInterfaceDescriptor(); \
}
class PlatformCodeStub : public CodeStub {
public:
// Retrieve the code for the stub. Generate the code if needed.
- Handle<Code> GenerateCode() OVERRIDE;
-
- Code::Kind GetCodeKind() const OVERRIDE { return Code::STUB; }
+ Handle<Code> GenerateCode() override;
protected:
explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) {}
@@ -347,7 +385,6 @@
enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
-enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS };
class CodeStubDescriptor {
@@ -362,8 +399,7 @@
void Initialize(Register stack_parameter_count,
Address deoptimization_handler = NULL,
int hint_stack_parameter_count = -1,
- StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE,
- HandlerArgumentsMode handler_mode = DONT_PASS_ARGUMENTS);
+ StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
void SetMissHandler(ExternalReference handler) {
miss_handler_ = handler;
@@ -376,12 +412,24 @@
void set_call_descriptor(CallInterfaceDescriptor d) { call_descriptor_ = d; }
CallInterfaceDescriptor call_descriptor() const { return call_descriptor_; }
- int GetEnvironmentParameterCount() const {
- return call_descriptor().GetEnvironmentParameterCount();
+ int GetRegisterParameterCount() const {
+ return call_descriptor().GetRegisterParameterCount();
}
- Representation GetEnvironmentParameterRepresentation(int index) const {
- return call_descriptor().GetEnvironmentParameterRepresentation(index);
+ int GetStackParameterCount() const {
+ return call_descriptor().GetStackParameterCount();
+ }
+
+ int GetParameterCount() const {
+ return call_descriptor().GetParameterCount();
+ }
+
+ Register GetRegisterParameter(int index) const {
+ return call_descriptor().GetRegisterParameter(index);
+ }
+
+ Type* GetParameterType(int index) const {
+ return call_descriptor().GetParameterType(index);
}
ExternalReference miss_handler() const {
@@ -393,14 +441,9 @@
return has_miss_handler_;
}
- bool IsEnvironmentParameterCountRegister(int index) const {
- return call_descriptor().GetEnvironmentParameterRegister(index).is(
- stack_parameter_count_);
- }
-
int GetHandlerParameterCount() const {
- int params = call_descriptor().GetEnvironmentParameterCount();
- if (handler_arguments_mode_ == PASS_ARGUMENTS) {
+ int params = GetParameterCount();
+ if (PassesArgumentsToDeoptimizationHandler()) {
params += 1;
}
return params;
@@ -412,6 +455,10 @@
Address deoptimization_handler() const { return deoptimization_handler_; }
private:
+ bool PassesArgumentsToDeoptimizationHandler() const {
+ return stack_parameter_count_.is_valid();
+ }
+
CallInterfaceDescriptor call_descriptor_;
Register stack_parameter_count_;
// If hint_stack_parameter_count_ > 0, the code stub can optimize the
@@ -420,7 +467,6 @@
StubFunctionMode function_mode_;
Address deoptimization_handler_;
- HandlerArgumentsMode handler_arguments_mode_;
ExternalReference miss_handler_;
bool has_miss_handler_;
@@ -434,8 +480,6 @@
INITIALIZED
};
- Code::Kind GetCodeKind() const OVERRIDE { return Code::STUB; }
-
template<class SubClass>
static Handle<Code> GetUninitialized(Isolate* isolate) {
SubClass::GenerateAheadOfTime(isolate);
@@ -443,7 +487,7 @@
}
// Retrieve the code for the stub. Generate the code if needed.
- Handle<Code> GenerateCode() OVERRIDE = 0;
+ Handle<Code> GenerateCode() override = 0;
bool IsUninitialized() const { return IsMissBits::decode(minor_key_); }
@@ -477,6 +521,28 @@
};
+class TurboFanCodeStub : public CodeStub {
+ public:
+ // Retrieve the code for the stub. Generate the code if needed.
+ Handle<Code> GenerateCode() override;
+
+ int GetStackParameterCount() const override {
+ return GetCallInterfaceDescriptor().GetStackParameterCount();
+ }
+
+ Code::StubType GetStubType() const override { return Code::FAST; }
+
+ protected:
+ explicit TurboFanCodeStub(Isolate* isolate) : CodeStub(isolate) {}
+
+ virtual void GenerateAssembly(
+ compiler::CodeStubAssembler* assembler) const = 0;
+
+ private:
+ DEFINE_CODE_STUB_BASE(TurboFanCodeStub, CodeStub);
+};
+
+
// Helper interface to prepare to/restore after making runtime calls.
class RuntimeCallHelper {
public:
@@ -494,7 +560,8 @@
};
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
#if V8_TARGET_ARCH_IA32
#include "src/ia32/code-stubs-ia32.h"
@@ -504,6 +571,8 @@
#include "src/arm64/code-stubs-arm64.h"
#elif V8_TARGET_ARCH_ARM
#include "src/arm/code-stubs-arm.h"
+#elif V8_TARGET_ARCH_PPC
+#include "src/ppc/code-stubs-ppc.h"
#elif V8_TARGET_ARCH_MIPS
#include "src/mips/code-stubs-mips.h"
#elif V8_TARGET_ARCH_MIPS64
@@ -524,9 +593,9 @@
public:
StubRuntimeCallHelper() {}
- virtual void BeforeCall(MacroAssembler* masm) const;
+ void BeforeCall(MacroAssembler* masm) const override;
- virtual void AfterCall(MacroAssembler* masm) const;
+ void AfterCall(MacroAssembler* masm) const override;
};
@@ -535,13 +604,47 @@
public:
NopRuntimeCallHelper() {}
- virtual void BeforeCall(MacroAssembler* masm) const {}
+ void BeforeCall(MacroAssembler* masm) const override {}
- virtual void AfterCall(MacroAssembler* masm) const {}
+ void AfterCall(MacroAssembler* masm) const override {}
};
-class NumberToStringStub FINAL : public HydrogenCodeStub {
+class StringLengthStub : public TurboFanCodeStub {
+ public:
+ explicit StringLengthStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
+
+ Code::Kind GetCodeKind() const override { return Code::HANDLER; }
+ InlineCacheState GetICState() const override { return MONOMORPHIC; }
+ ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
+
+ void GenerateAssembly(compiler::CodeStubAssembler* assembler) const override;
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
+ DEFINE_CODE_STUB(StringLength, TurboFanCodeStub);
+};
+
+
+enum StringAddFlags {
+ // Omit both parameter checks.
+ STRING_ADD_CHECK_NONE = 0,
+ // Check left parameter.
+ STRING_ADD_CHECK_LEFT = 1 << 0,
+ // Check right parameter.
+ STRING_ADD_CHECK_RIGHT = 1 << 1,
+ // Check both parameters.
+ STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT,
+ // Convert parameters when check fails (instead of throwing an exception).
+ STRING_ADD_CONVERT = 1 << 2,
+ STRING_ADD_CONVERT_LEFT = STRING_ADD_CHECK_LEFT | STRING_ADD_CONVERT,
+ STRING_ADD_CONVERT_RIGHT = STRING_ADD_CHECK_RIGHT | STRING_ADD_CONVERT
+};
+
+
+std::ostream& operator<<(std::ostream& os, const StringAddFlags& flags);
+
+
+class NumberToStringStub final : public HydrogenCodeStub {
public:
explicit NumberToStringStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
@@ -553,43 +656,54 @@
};
+class TypeofStub final : public HydrogenCodeStub {
+ public:
+ explicit TypeofStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
+
+ // Parameters accessed via CodeStubGraphBuilder::GetParameter()
+ static const int kObject = 0;
+
+ static void GenerateAheadOfTime(Isolate* isolate);
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(Typeof);
+ DEFINE_HYDROGEN_CODE_STUB(Typeof, HydrogenCodeStub);
+};
+
+
class FastNewClosureStub : public HydrogenCodeStub {
public:
- FastNewClosureStub(Isolate* isolate, StrictMode strict_mode,
+ FastNewClosureStub(Isolate* isolate, LanguageMode language_mode,
FunctionKind kind)
: HydrogenCodeStub(isolate) {
DCHECK(IsValidFunctionKind(kind));
- set_sub_minor_key(StrictModeBits::encode(strict_mode) |
+ set_sub_minor_key(LanguageModeBits::encode(language_mode) |
FunctionKindBits::encode(kind));
}
- StrictMode strict_mode() const {
- return StrictModeBits::decode(sub_minor_key());
+ LanguageMode language_mode() const {
+ return LanguageModeBits::decode(sub_minor_key());
}
FunctionKind kind() const {
return FunctionKindBits::decode(sub_minor_key());
}
- bool is_arrow() const { return IsArrowFunction(kind()); }
- bool is_generator() const { return IsGeneratorFunction(kind()); }
- bool is_concise_method() const { return IsConciseMethod(kind()); }
- bool is_default_constructor() const { return IsDefaultConstructor(kind()); }
private:
- class StrictModeBits : public BitField<StrictMode, 0, 1> {};
- class FunctionKindBits : public BitField<FunctionKind, 1, 4> {};
+ STATIC_ASSERT(LANGUAGE_END == 3);
+ class LanguageModeBits : public BitField<LanguageMode, 0, 2> {};
+ class FunctionKindBits : public BitField<FunctionKind, 2, 8> {};
DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewClosure);
DEFINE_HYDROGEN_CODE_STUB(FastNewClosure, HydrogenCodeStub);
};
-class FastNewContextStub FINAL : public HydrogenCodeStub {
+class FastNewContextStub final : public HydrogenCodeStub {
public:
static const int kMaximumSlots = 64;
FastNewContextStub(Isolate* isolate, int slots) : HydrogenCodeStub(isolate) {
- DCHECK(slots > 0 && slots <= kMaximumSlots);
+ DCHECK(slots >= 0 && slots <= kMaximumSlots);
set_sub_minor_key(SlotsBits::encode(slots));
}
@@ -606,6 +720,16 @@
};
+class FastCloneRegExpStub final : public HydrogenCodeStub {
+ public:
+ explicit FastCloneRegExpStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
+
+ private:
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneRegExp);
+ DEFINE_HYDROGEN_CODE_STUB(FastCloneRegExp, HydrogenCodeStub);
+};
+
+
class FastCloneShallowArrayStub : public HydrogenCodeStub {
public:
FastCloneShallowArrayStub(Isolate* isolate,
@@ -660,47 +784,47 @@
};
-class InstanceofStub: public PlatformCodeStub {
+class CreateWeakCellStub : public HydrogenCodeStub {
public:
- enum Flags {
- kNoFlags = 0,
- kArgsInRegisters = 1 << 0,
- kCallSiteInlineCheck = 1 << 1,
- kReturnTrueFalseObject = 1 << 2
- };
+ explicit CreateWeakCellStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
- InstanceofStub(Isolate* isolate, Flags flags) : PlatformCodeStub(isolate) {
- minor_key_ = FlagBits::encode(flags);
+ static void GenerateAheadOfTime(Isolate* isolate);
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateWeakCell);
+ DEFINE_HYDROGEN_CODE_STUB(CreateWeakCell, HydrogenCodeStub);
+};
+
+
+class GrowArrayElementsStub : public HydrogenCodeStub {
+ public:
+ GrowArrayElementsStub(Isolate* isolate, bool is_js_array, ElementsKind kind)
+ : HydrogenCodeStub(isolate) {
+ set_sub_minor_key(ElementsKindBits::encode(kind) |
+ IsJsArrayBits::encode(is_js_array));
}
- static Register left() { return InstanceofDescriptor::left(); }
- static Register right() { return InstanceofDescriptor::right(); }
-
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
- if (HasArgsInRegisters()) {
- return InstanceofDescriptor(isolate());
- }
- return ContextOnlyDescriptor(isolate());
+ ElementsKind elements_kind() const {
+ return ElementsKindBits::decode(sub_minor_key());
}
+ bool is_js_array() const { return IsJsArrayBits::decode(sub_minor_key()); }
+
private:
- Flags flags() const { return FlagBits::decode(minor_key_); }
+ class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
+ class IsJsArrayBits : public BitField<bool, ElementsKindBits::kNext, 1> {};
- bool HasArgsInRegisters() const { return (flags() & kArgsInRegisters) != 0; }
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(GrowArrayElements);
+ DEFINE_HYDROGEN_CODE_STUB(GrowArrayElements, HydrogenCodeStub);
+};
- bool HasCallSiteInlineCheck() const {
- return (flags() & kCallSiteInlineCheck) != 0;
- }
- bool ReturnTrueFalseObject() const {
- return (flags() & kReturnTrueFalseObject) != 0;
- }
+class InstanceOfStub final : public PlatformCodeStub {
+ public:
+ explicit InstanceOfStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
- void PrintName(std::ostream& os) const OVERRIDE; // NOLINT
-
- class FlagBits : public BitField<Flags, 0, 3> {};
-
- DEFINE_PLATFORM_CODE_STUB(Instanceof, PlatformCodeStub);
+ private:
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(InstanceOf);
+ DEFINE_PLATFORM_CODE_STUB(InstanceOf, PlatformCodeStub);
};
@@ -727,7 +851,7 @@
void GenerateDispatchToArrayStub(MacroAssembler* masm,
AllocationSiteOverrideMode mode);
- void PrintName(std::ostream& os) const OVERRIDE; // NOLINT
+ void PrintName(std::ostream& os) const override; // NOLINT
class ArgumentCountBits : public BitField<ArgumentCountKey, 0, 2> {};
@@ -757,7 +881,7 @@
minor_key_ = ExponentTypeBits::encode(exponent_type);
}
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
if (exponent_type() == TAGGED) {
return MathPowTaggedDescriptor(isolate());
} else if (exponent_type() == INTEGER) {
@@ -785,25 +909,17 @@
minor_key_ = state.GetExtraICState();
}
- static int ExtractArgcFromMinorKey(int minor_key) {
- CallICState state(static_cast<ExtraICState>(minor_key));
- return state.arg_count();
- }
+ Code::Kind GetCodeKind() const override { return Code::CALL_IC; }
- Code::Kind GetCodeKind() const OVERRIDE { return Code::CALL_IC; }
+ InlineCacheState GetICState() const override { return GENERIC; }
- InlineCacheState GetICState() const OVERRIDE { return DEFAULT; }
-
- ExtraICState GetExtraICState() const FINAL {
+ ExtraICState GetExtraICState() const final {
return static_cast<ExtraICState>(minor_key_);
}
protected:
- bool CallAsMethod() const {
- return state().call_type() == CallICState::METHOD;
- }
-
- int arg_count() const { return state().arg_count(); }
+ int arg_count() const { return state().argc(); }
+ ConvertReceiverMode convert_mode() const { return state().convert_mode(); }
CallICState state() const {
return CallICState(static_cast<ExtraICState>(minor_key_));
@@ -811,45 +927,29 @@
// Code generation helpers.
void GenerateMiss(MacroAssembler* masm);
+ void HandleArrayCase(MacroAssembler* masm, Label* miss);
private:
- void PrintState(std::ostream& os) const OVERRIDE; // NOLINT
+ void PrintState(std::ostream& os) const override; // NOLINT
- DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback);
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedbackAndVector);
DEFINE_PLATFORM_CODE_STUB(CallIC, PlatformCodeStub);
};
-class CallIC_ArrayStub: public CallICStub {
- public:
- CallIC_ArrayStub(Isolate* isolate, const CallICState& state_in)
- : CallICStub(isolate, state_in) {}
-
- InlineCacheState GetICState() const FINAL { return MONOMORPHIC; }
-
- private:
- void PrintState(std::ostream& os) const OVERRIDE; // NOLINT
-
- DEFINE_PLATFORM_CODE_STUB(CallIC_Array, CallICStub);
-};
-
-
// TODO(verwaest): Translate to hydrogen code stub.
class FunctionPrototypeStub : public PlatformCodeStub {
public:
explicit FunctionPrototypeStub(Isolate* isolate)
: PlatformCodeStub(isolate) {}
- Code::Kind GetCodeKind() const OVERRIDE { return Code::HANDLER; }
+ Code::Kind GetCodeKind() const override { return Code::HANDLER; }
// TODO(mvstanton): only the receiver register is accessed. When this is
// translated to a hydrogen code stub, a new CallInterfaceDescriptor
// should be created that just uses that register for more efficient code.
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
- if (FLAG_vector_ics) {
- return VectorLoadICDescriptor(isolate());
- }
- return LoadDescriptor(isolate());
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
+ return LoadWithVectorDescriptor(isolate());
}
DEFINE_PLATFORM_CODE_STUB(FunctionPrototype, PlatformCodeStub);
@@ -862,8 +962,8 @@
explicit LoadIndexedInterceptorStub(Isolate* isolate)
: PlatformCodeStub(isolate) {}
- Code::Kind GetCodeKind() const OVERRIDE { return Code::HANDLER; }
- Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+ Code::Kind GetCodeKind() const override { return Code::HANDLER; }
+ Code::StubType GetStubType() const override { return Code::FAST; }
DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
DEFINE_PLATFORM_CODE_STUB(LoadIndexedInterceptor, PlatformCodeStub);
@@ -875,8 +975,8 @@
explicit LoadIndexedStringStub(Isolate* isolate)
: PlatformCodeStub(isolate) {}
- Code::Kind GetCodeKind() const OVERRIDE { return Code::HANDLER; }
- Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+ Code::Kind GetCodeKind() const override { return Code::HANDLER; }
+ Code::StubType GetStubType() const override { return Code::FAST; }
DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
DEFINE_PLATFORM_CODE_STUB(LoadIndexedString, PlatformCodeStub);
@@ -885,13 +985,13 @@
class HandlerStub : public HydrogenCodeStub {
public:
- Code::Kind GetCodeKind() const OVERRIDE { return Code::HANDLER; }
- ExtraICState GetExtraICState() const OVERRIDE { return kind(); }
- InlineCacheState GetICState() const OVERRIDE { return MONOMORPHIC; }
+ Code::Kind GetCodeKind() const override { return Code::HANDLER; }
+ ExtraICState GetExtraICState() const override { return kind(); }
+ InlineCacheState GetICState() const override { return MONOMORPHIC; }
- void InitializeDescriptor(CodeStubDescriptor* descriptor) OVERRIDE;
+ void InitializeDescriptor(CodeStubDescriptor* descriptor) override;
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE;
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override;
protected:
explicit HandlerStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
@@ -915,8 +1015,8 @@
}
protected:
- Code::Kind kind() const OVERRIDE { return Code::LOAD_IC; }
- Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+ Code::Kind kind() const override { return Code::LOAD_IC; }
+ Code::StubType GetStubType() const override { return Code::FAST; }
private:
class LoadFieldByIndexBits : public BitField<int, 0, 13> {};
@@ -925,20 +1025,65 @@
};
+class ArrayBufferViewLoadFieldStub : public HandlerStub {
+ public:
+ ArrayBufferViewLoadFieldStub(Isolate* isolate, FieldIndex index)
+ : HandlerStub(isolate) {
+ int property_index_key = index.GetFieldAccessStubKey();
+ set_sub_minor_key(
+ ArrayBufferViewLoadFieldByIndexBits::encode(property_index_key));
+ }
+
+ FieldIndex index() const {
+ int property_index_key =
+ ArrayBufferViewLoadFieldByIndexBits::decode(sub_minor_key());
+ return FieldIndex::FromFieldAccessStubKey(property_index_key);
+ }
+
+ protected:
+ Code::Kind kind() const override { return Code::LOAD_IC; }
+ Code::StubType GetStubType() const override { return Code::FAST; }
+
+ private:
+ class ArrayBufferViewLoadFieldByIndexBits : public BitField<int, 0, 13> {};
+
+ DEFINE_HANDLER_CODE_STUB(ArrayBufferViewLoadField, HandlerStub);
+};
+
+
class KeyedLoadSloppyArgumentsStub : public HandlerStub {
public:
explicit KeyedLoadSloppyArgumentsStub(Isolate* isolate)
: HandlerStub(isolate) {}
protected:
- Code::Kind kind() const OVERRIDE { return Code::KEYED_LOAD_IC; }
- Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+ Code::Kind kind() const override { return Code::KEYED_LOAD_IC; }
+ Code::StubType GetStubType() const override { return Code::FAST; }
private:
DEFINE_HANDLER_CODE_STUB(KeyedLoadSloppyArguments, HandlerStub);
};
+class CommonStoreModeBits : public BitField<KeyedAccessStoreMode, 0, 3> {};
+
+class KeyedStoreSloppyArgumentsStub : public HandlerStub {
+ public:
+ explicit KeyedStoreSloppyArgumentsStub(Isolate* isolate,
+ KeyedAccessStoreMode mode)
+ : HandlerStub(isolate) {
+ set_sub_minor_key(CommonStoreModeBits::encode(mode));
+ }
+
+ protected:
+ Code::Kind kind() const override { return Code::KEYED_STORE_IC; }
+ Code::StubType GetStubType() const override { return Code::FAST; }
+
+ private:
+ DEFINE_HANDLER_CODE_STUB(KeyedStoreSloppyArguments, HandlerStub);
+};
+
+
class LoadConstantStub : public HandlerStub {
public:
LoadConstantStub(Isolate* isolate, int constant_index)
@@ -951,8 +1096,8 @@
}
protected:
- Code::Kind kind() const OVERRIDE { return Code::LOAD_IC; }
- Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+ Code::Kind kind() const override { return Code::LOAD_IC; }
+ Code::StubType GetStubType() const override { return Code::FAST; }
private:
class ConstantIndexBits : public BitField<int, 0, kSubMinorKeyBits> {};
@@ -961,18 +1106,6 @@
};
-class StringLengthStub: public HandlerStub {
- public:
- explicit StringLengthStub(Isolate* isolate) : HandlerStub(isolate) {}
-
- protected:
- Code::Kind kind() const OVERRIDE { return Code::LOAD_IC; }
- Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
-
- DEFINE_HANDLER_CODE_STUB(StringLength, HandlerStub);
-};
-
-
class StoreFieldStub : public HandlerStub {
public:
StoreFieldStub(Isolate* isolate, FieldIndex index,
@@ -995,8 +1128,8 @@
}
protected:
- Code::Kind kind() const OVERRIDE { return Code::STORE_IC; }
- Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+ Code::Kind kind() const override { return Code::STORE_IC; }
+ Code::StubType GetStubType() const override { return Code::FAST; }
private:
class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
@@ -1006,6 +1139,63 @@
};
+// Register and parameter access methods are specified here instead of in
+// the CallInterfaceDescriptor because the stub uses a different descriptor
+// if FLAG_vector_stores is on.
+class StoreTransitionHelper {
+ public:
+ static Register ReceiverRegister() {
+ return StoreTransitionDescriptor::ReceiverRegister();
+ }
+
+ static Register NameRegister() {
+ return StoreTransitionDescriptor::NameRegister();
+ }
+
+ static Register ValueRegister() {
+ return StoreTransitionDescriptor::ValueRegister();
+ }
+
+ static Register SlotRegister() {
+ return VectorStoreTransitionDescriptor::SlotRegister();
+ }
+
+ static Register VectorRegister() {
+ return VectorStoreTransitionDescriptor::VectorRegister();
+ }
+
+ static Register MapRegister() {
+ return VectorStoreTransitionDescriptor::MapRegister();
+ }
+
+ static int ReceiverIndex() {
+ return StoreTransitionDescriptor::kReceiverIndex;
+ }
+
+ static int NameIndex() { return StoreTransitionDescriptor::kReceiverIndex; }
+
+ static int ValueIndex() { return StoreTransitionDescriptor::kValueIndex; }
+
+ static int MapIndex() {
+ DCHECK(static_cast<int>(VectorStoreTransitionDescriptor::kMapIndex) ==
+ static_cast<int>(StoreTransitionDescriptor::kMapIndex));
+ return StoreTransitionDescriptor::kMapIndex;
+ }
+
+ static int VectorIndex() {
+ if (HasVirtualSlotArg()) {
+ return VectorStoreTransitionDescriptor::kVirtualSlotVectorIndex;
+ }
+ return VectorStoreTransitionDescriptor::kVectorIndex;
+ }
+
+ // Some platforms don't have a slot arg.
+ static bool HasVirtualSlotArg() {
+ return SlotRegister().is(no_reg);
+ }
+};
+
+
class StoreTransitionStub : public HandlerStub {
public:
enum StoreMode {
@@ -1045,11 +1235,11 @@
return StoreModeBits::decode(sub_minor_key());
}
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE;
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override;
protected:
- Code::Kind kind() const OVERRIDE { return Code::STORE_IC; }
- Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+ Code::Kind kind() const override { return Code::STORE_IC; }
+ Code::StubType GetStubType() const override { return Code::FAST; }
private:
class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
@@ -1062,41 +1252,50 @@
class StoreGlobalStub : public HandlerStub {
public:
- StoreGlobalStub(Isolate* isolate, bool is_constant, bool check_global)
+ StoreGlobalStub(Isolate* isolate, PropertyCellType type,
+ Maybe<PropertyCellConstantType> constant_type,
+ bool check_global)
: HandlerStub(isolate) {
- set_sub_minor_key(IsConstantBits::encode(is_constant) |
+ PropertyCellConstantType encoded_constant_type =
+ constant_type.FromMaybe(PropertyCellConstantType::kSmi);
+ set_sub_minor_key(CellTypeBits::encode(type) |
+ ConstantTypeBits::encode(encoded_constant_type) |
CheckGlobalBits::encode(check_global));
}
- static Handle<HeapObject> global_placeholder(Isolate* isolate) {
+ static Handle<HeapObject> property_cell_placeholder(Isolate* isolate) {
return isolate->factory()->uninitialized_value();
}
- Handle<Code> GetCodeCopyFromTemplate(Handle<GlobalObject> global,
- Handle<PropertyCell> cell) {
- if (check_global()) {
- Code::FindAndReplacePattern pattern;
- pattern.Add(Handle<Map>(global_placeholder(isolate())->map()), global);
- pattern.Add(isolate()->factory()->meta_map(), Handle<Map>(global->map()));
- pattern.Add(isolate()->factory()->global_property_cell_map(), cell);
- return CodeStub::GetCodeCopy(pattern);
- } else {
- Code::FindAndReplacePattern pattern;
- pattern.Add(isolate()->factory()->global_property_cell_map(), cell);
- return CodeStub::GetCodeCopy(pattern);
- }
+ static Handle<HeapObject> global_map_placeholder(Isolate* isolate) {
+ return isolate->factory()->termination_exception();
}
- Code::Kind kind() const OVERRIDE { return Code::STORE_IC; }
+ Handle<Code> GetCodeCopyFromTemplate(Handle<JSGlobalObject> global,
+ Handle<PropertyCell> cell) {
+ Code::FindAndReplacePattern pattern;
+ if (check_global()) {
+ pattern.Add(handle(global_map_placeholder(isolate())->map()),
+ Map::WeakCellForMap(Handle<Map>(global->map())));
+ }
+ pattern.Add(handle(property_cell_placeholder(isolate())->map()),
+ isolate()->factory()->NewWeakCell(cell));
+ return CodeStub::GetCodeCopy(pattern);
+ }
- bool is_constant() const { return IsConstantBits::decode(sub_minor_key()); }
+ Code::Kind kind() const override { return Code::STORE_IC; }
+
+ PropertyCellType cell_type() const {
+ return CellTypeBits::decode(sub_minor_key());
+ }
+
+ PropertyCellConstantType constant_type() const {
+ DCHECK(PropertyCellType::kConstantType == cell_type());
+ return ConstantTypeBits::decode(sub_minor_key());
+ }
bool check_global() const { return CheckGlobalBits::decode(sub_minor_key()); }
- void set_is_constant(bool value) {
- set_sub_minor_key(IsConstantBits::update(sub_minor_key(), value));
- }
-
Representation representation() {
return Representation::FromKind(
RepresentationBits::decode(sub_minor_key()));
@@ -1107,24 +1306,98 @@
}
private:
- class IsConstantBits: public BitField<bool, 0, 1> {};
- class RepresentationBits: public BitField<Representation::Kind, 1, 8> {};
- class CheckGlobalBits: public BitField<bool, 9, 1> {};
+ class CellTypeBits : public BitField<PropertyCellType, 0, 2> {};
+ class ConstantTypeBits : public BitField<PropertyCellConstantType, 2, 2> {};
+ class RepresentationBits : public BitField<Representation::Kind, 4, 8> {};
+ class CheckGlobalBits : public BitField<bool, 12, 1> {};
DEFINE_HANDLER_CODE_STUB(StoreGlobal, HandlerStub);
};
+class LoadGlobalViaContextStub final : public PlatformCodeStub {
+ public:
+ static const int kMaximumDepth = 15;
+
+ LoadGlobalViaContextStub(Isolate* isolate, int depth)
+ : PlatformCodeStub(isolate) {
+ minor_key_ = DepthBits::encode(depth);
+ }
+
+ int depth() const { return DepthBits::decode(minor_key_); }
+
+ private:
+ class DepthBits : public BitField<int, 0, 4> {};
+ STATIC_ASSERT(DepthBits::kMax == kMaximumDepth);
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadGlobalViaContext);
+ DEFINE_PLATFORM_CODE_STUB(LoadGlobalViaContext, PlatformCodeStub);
+};
+
+
+class StoreGlobalViaContextStub final : public PlatformCodeStub {
+ public:
+ static const int kMaximumDepth = 15;
+
+ StoreGlobalViaContextStub(Isolate* isolate, int depth,
+ LanguageMode language_mode)
+ : PlatformCodeStub(isolate) {
+ minor_key_ =
+ DepthBits::encode(depth) | LanguageModeBits::encode(language_mode);
+ }
+
+ int depth() const { return DepthBits::decode(minor_key_); }
+ LanguageMode language_mode() const {
+ return LanguageModeBits::decode(minor_key_);
+ }
+
+ private:
+ class DepthBits : public BitField<int, 0, 4> {};
+ STATIC_ASSERT(DepthBits::kMax == kMaximumDepth);
+ class LanguageModeBits : public BitField<LanguageMode, 4, 2> {};
+ STATIC_ASSERT(LANGUAGE_END == 3);
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreGlobalViaContext);
+ DEFINE_PLATFORM_CODE_STUB(StoreGlobalViaContext, PlatformCodeStub);
+};
+
+
class CallApiFunctionStub : public PlatformCodeStub {
public:
- CallApiFunctionStub(Isolate* isolate,
- bool is_store,
- bool call_data_undefined,
- int argc) : PlatformCodeStub(isolate) {
+ explicit CallApiFunctionStub(Isolate* isolate, bool call_data_undefined)
+ : PlatformCodeStub(isolate) {
+ minor_key_ = CallDataUndefinedBits::encode(call_data_undefined);
+ }
+
+ private:
+ bool call_data_undefined() const {
+ return CallDataUndefinedBits::decode(minor_key_);
+ }
+
+ class CallDataUndefinedBits : public BitField<bool, 0, 1> {};
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiFunction);
+ DEFINE_PLATFORM_CODE_STUB(CallApiFunction, PlatformCodeStub);
+};
+
+
+class CallApiAccessorStub : public PlatformCodeStub {
+ public:
+ CallApiAccessorStub(Isolate* isolate, bool is_store, bool call_data_undefined)
+ : PlatformCodeStub(isolate) {
minor_key_ = IsStoreBits::encode(is_store) |
CallDataUndefinedBits::encode(call_data_undefined) |
+ ArgumentBits::encode(is_store ? 1 : 0);
+ }
+
+ protected:
+ // For CallApiFunctionWithFixedArgsStub, see below.
+ static const int kArgBits = 3;
+ CallApiAccessorStub(Isolate* isolate, int argc, bool call_data_undefined)
+ : PlatformCodeStub(isolate) {
+ minor_key_ = IsStoreBits::encode(false) |
+ CallDataUndefinedBits::encode(call_data_undefined) |
ArgumentBits::encode(argc);
- DCHECK(!is_store || argc == 1);
}
private:
@@ -1136,14 +1409,31 @@
class IsStoreBits: public BitField<bool, 0, 1> {};
class CallDataUndefinedBits: public BitField<bool, 1, 1> {};
- class ArgumentBits: public BitField<int, 2, Code::kArgumentsBits> {};
- STATIC_ASSERT(Code::kArgumentsBits + 2 <= kStubMinorKeyBits);
+ class ArgumentBits : public BitField<int, 2, kArgBits> {};
- DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiFunction);
- DEFINE_PLATFORM_CODE_STUB(CallApiFunction, PlatformCodeStub);
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiAccessor);
+ DEFINE_PLATFORM_CODE_STUB(CallApiAccessor, PlatformCodeStub);
};
+// TODO(dcarney): see if it's possible to remove this later without performance
+// degradation.
+// This is not a real stub, but a way of generating the CallApiAccessorStub
+// (which has the same abi) which makes it clear that it is not an accessor.
+class CallApiFunctionWithFixedArgsStub : public CallApiAccessorStub {
+ public:
+ static const int kMaxFixedArgs = (1 << kArgBits) - 1;
+ CallApiFunctionWithFixedArgsStub(Isolate* isolate, int argc,
+ bool call_data_undefined)
+ : CallApiAccessorStub(isolate, argc, call_data_undefined) {
+ DCHECK(0 <= argc && argc <= kMaxFixedArgs);
+ }
+};
+
+
+typedef ApiAccessorDescriptor ApiFunctionWithFixedArgsDescriptor;
+
+
class CallApiGetterStub : public PlatformCodeStub {
public:
explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
@@ -1155,10 +1445,9 @@
class BinaryOpICStub : public HydrogenCodeStub {
public:
- BinaryOpICStub(Isolate* isolate, Token::Value op,
- OverwriteMode mode = NO_OVERWRITE)
+ BinaryOpICStub(Isolate* isolate, Token::Value op, Strength strength)
: HydrogenCodeStub(isolate, UNINITIALIZED) {
- BinaryOpICState state(isolate, op, mode);
+ BinaryOpICState state(isolate, op, strength);
set_sub_minor_key(state.GetExtraICState());
}
@@ -1169,11 +1458,11 @@
static void GenerateAheadOfTime(Isolate* isolate);
- Code::Kind GetCodeKind() const OVERRIDE { return Code::BINARY_OP_IC; }
+ Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
- InlineCacheState GetICState() const FINAL { return state().GetICState(); }
+ InlineCacheState GetICState() const final { return state().GetICState(); }
- ExtraICState GetExtraICState() const FINAL {
+ ExtraICState GetExtraICState() const final {
return static_cast<ExtraICState>(sub_minor_key());
}
@@ -1181,7 +1470,7 @@
return BinaryOpICState(isolate(), GetExtraICState());
}
- void PrintState(std::ostream& os) const FINAL; // NOLINT
+ void PrintState(std::ostream& os) const final; // NOLINT
// Parameters accessed via CodeStubGraphBuilder::GetParameter()
static const int kLeft = 0;
@@ -1198,7 +1487,7 @@
// TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail
// call support for stubs in Hydrogen.
-class BinaryOpICWithAllocationSiteStub FINAL : public PlatformCodeStub {
+class BinaryOpICWithAllocationSiteStub final : public PlatformCodeStub {
public:
BinaryOpICWithAllocationSiteStub(Isolate* isolate,
const BinaryOpICState& state)
@@ -1214,15 +1503,15 @@
return CodeStub::GetCodeCopy(pattern);
}
- Code::Kind GetCodeKind() const OVERRIDE { return Code::BINARY_OP_IC; }
+ Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
- InlineCacheState GetICState() const OVERRIDE { return state().GetICState(); }
+ InlineCacheState GetICState() const override { return state().GetICState(); }
- ExtraICState GetExtraICState() const OVERRIDE {
+ ExtraICState GetExtraICState() const override {
return static_cast<ExtraICState>(minor_key_);
}
- void PrintState(std::ostream& os) const OVERRIDE; // NOLINT
+ void PrintState(std::ostream& os) const override; // NOLINT
private:
BinaryOpICState state() const {
@@ -1237,17 +1526,16 @@
};
-class BinaryOpWithAllocationSiteStub FINAL : public BinaryOpICStub {
+class BinaryOpWithAllocationSiteStub final : public BinaryOpICStub {
public:
- BinaryOpWithAllocationSiteStub(Isolate* isolate,
- Token::Value op,
- OverwriteMode mode)
- : BinaryOpICStub(isolate, op, mode) {}
+ BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op,
+ Strength strength)
+ : BinaryOpICStub(isolate, op, strength) {}
BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
: BinaryOpICStub(isolate, state) {}
- Code::Kind GetCodeKind() const FINAL { return Code::STUB; }
+ Code::Kind GetCodeKind() const final { return Code::STUB; }
// Parameters accessed via CodeStubGraphBuilder::GetParameter()
static const int kAllocationSite = 0;
@@ -1259,19 +1547,7 @@
};
-enum StringAddFlags {
- // Omit both parameter checks.
- STRING_ADD_CHECK_NONE = 0,
- // Check left parameter.
- STRING_ADD_CHECK_LEFT = 1 << 0,
- // Check right parameter.
- STRING_ADD_CHECK_RIGHT = 1 << 1,
- // Check both parameters.
- STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT
-};
-
-
-class StringAddStub FINAL : public HydrogenCodeStub {
+class StringAddStub final : public HydrogenCodeStub {
public:
StringAddStub(Isolate* isolate, StringAddFlags flags,
PretenureFlag pretenure_flag)
@@ -1293,10 +1569,10 @@
static const int kRight = 1;
private:
- class StringAddFlagsBits: public BitField<StringAddFlags, 0, 2> {};
- class PretenureFlagBits: public BitField<PretenureFlag, 2, 1> {};
+ class StringAddFlagsBits : public BitField<StringAddFlags, 0, 3> {};
+ class PretenureFlagBits : public BitField<PretenureFlag, 3, 1> {};
- void PrintBaseName(std::ostream& os) const OVERRIDE; // NOLINT
+ void PrintBaseName(std::ostream& os) const override; // NOLINT
DEFINE_CALL_INTERFACE_DESCRIPTOR(StringAdd);
DEFINE_HYDROGEN_CODE_STUB(StringAdd, HydrogenCodeStub);
@@ -1305,22 +1581,29 @@
class CompareICStub : public PlatformCodeStub {
public:
- CompareICStub(Isolate* isolate, Token::Value op, CompareICState::State left,
- CompareICState::State right, CompareICState::State state)
+ CompareICStub(Isolate* isolate, Token::Value op, Strength strength,
+ CompareICState::State left, CompareICState::State right,
+ CompareICState::State state)
: PlatformCodeStub(isolate) {
DCHECK(Token::IsCompareOp(op));
- minor_key_ = OpBits::encode(op - Token::EQ) | LeftStateBits::encode(left) |
- RightStateBits::encode(right) | StateBits::encode(state);
+ minor_key_ = OpBits::encode(op - Token::EQ) |
+ StrengthBits::encode(is_strong(strength)) |
+ LeftStateBits::encode(left) | RightStateBits::encode(right) |
+ StateBits::encode(state);
}
void set_known_map(Handle<Map> map) { known_map_ = map; }
- InlineCacheState GetICState() const OVERRIDE;
+ InlineCacheState GetICState() const override;
Token::Value op() const {
return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
}
+ Strength strength() const {
+ return StrengthBits::decode(minor_key_) ? Strength::STRONG : Strength::WEAK;
+ }
+
CompareICState::State left() const {
return LeftStateBits::decode(minor_key_);
}
@@ -1330,31 +1613,33 @@
CompareICState::State state() const { return StateBits::decode(minor_key_); }
private:
- Code::Kind GetCodeKind() const OVERRIDE { return Code::COMPARE_IC; }
+ Code::Kind GetCodeKind() const override { return Code::COMPARE_IC; }
+ void GenerateBooleans(MacroAssembler* masm);
void GenerateSmis(MacroAssembler* masm);
void GenerateNumbers(MacroAssembler* masm);
void GenerateInternalizedStrings(MacroAssembler* masm);
void GenerateStrings(MacroAssembler* masm);
void GenerateUniqueNames(MacroAssembler* masm);
- void GenerateObjects(MacroAssembler* masm);
+ void GenerateReceivers(MacroAssembler* masm);
void GenerateMiss(MacroAssembler* masm);
- void GenerateKnownObjects(MacroAssembler* masm);
+ void GenerateKnownReceivers(MacroAssembler* masm);
void GenerateGeneric(MacroAssembler* masm);
bool strict() const { return op() == Token::EQ_STRICT; }
Condition GetCondition() const;
- void AddToSpecialCache(Handle<Code> new_object) OVERRIDE;
- bool FindCodeInSpecialCache(Code** code_out) OVERRIDE;
- bool UseSpecialCache() OVERRIDE {
- return state() == CompareICState::KNOWN_OBJECT;
+ void AddToSpecialCache(Handle<Code> new_object) override;
+ bool FindCodeInSpecialCache(Code** code_out) override;
+ bool UseSpecialCache() override {
+ return state() == CompareICState::KNOWN_RECEIVER;
}
class OpBits : public BitField<int, 0, 3> {};
- class LeftStateBits : public BitField<CompareICState::State, 3, 4> {};
- class RightStateBits : public BitField<CompareICState::State, 7, 4> {};
- class StateBits : public BitField<CompareICState::State, 11, 4> {};
+ class StrengthBits : public BitField<bool, 3, 1> {};
+ class LeftStateBits : public BitField<CompareICState::State, 4, 4> {};
+ class RightStateBits : public BitField<CompareICState::State, 8, 4> {};
+ class StateBits : public BitField<CompareICState::State, 12, 4> {};
Handle<Map> known_map_;
@@ -1383,7 +1668,7 @@
return CompareNilICStub(isolate, nil, UNINITIALIZED).GetCode();
}
- InlineCacheState GetICState() const OVERRIDE {
+ InlineCacheState GetICState() const override {
State state = this->state();
if (state.Contains(GENERIC)) {
return MEGAMORPHIC;
@@ -1394,9 +1679,9 @@
}
}
- Code::Kind GetCodeKind() const OVERRIDE { return Code::COMPARE_NIL_IC; }
+ Code::Kind GetCodeKind() const override { return Code::COMPARE_NIL_IC; }
- ExtraICState GetExtraICState() const OVERRIDE { return sub_minor_key(); }
+ ExtraICState GetExtraICState() const override { return sub_minor_key(); }
void UpdateStatus(Handle<Object> object);
@@ -1408,8 +1693,8 @@
set_sub_minor_key(TypesBits::update(sub_minor_key(), 0));
}
- void PrintState(std::ostream& os) const OVERRIDE; // NOLINT
- void PrintBaseName(std::ostream& os) const OVERRIDE; // NOLINT
+ void PrintState(std::ostream& os) const override; // NOLINT
+ void PrintBaseName(std::ostream& os) const override; // NOLINT
private:
CompareNilICStub(Isolate* isolate, NilValue nil,
@@ -1456,11 +1741,13 @@
class CEntryStub : public PlatformCodeStub {
public:
CEntryStub(Isolate* isolate, int result_size,
- SaveFPRegsMode save_doubles = kDontSaveFPRegs)
+ SaveFPRegsMode save_doubles = kDontSaveFPRegs,
+ ArgvMode argv_mode = kArgvOnStack)
: PlatformCodeStub(isolate) {
- minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs);
+ minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs) |
+ ArgvMode::encode(argv_mode == kArgvInRegister);
DCHECK(result_size == 1 || result_size == 2);
-#ifdef _WIN64
+#if _WIN64 || V8_TARGET_ARCH_PPC
minor_key_ = ResultSizeBits::update(minor_key_, result_size);
#endif // _WIN64
}
@@ -1473,14 +1760,16 @@
private:
bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
-#ifdef _WIN64
+ bool argv_in_register() const { return ArgvMode::decode(minor_key_); }
+#if _WIN64 || V8_TARGET_ARCH_PPC
int result_size() const { return ResultSizeBits::decode(minor_key_); }
#endif // _WIN64
- bool NeedsImmovableCode() OVERRIDE;
+ bool NeedsImmovableCode() override;
class SaveDoublesBits : public BitField<bool, 0, 1> {};
- class ResultSizeBits : public BitField<int, 1, 3> {};
+ class ArgvMode : public BitField<bool, 1, 1> {};
+ class ResultSizeBits : public BitField<int, 2, 3> {};
DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(CEntry, PlatformCodeStub);
@@ -1496,9 +1785,9 @@
}
private:
- void FinishCode(Handle<Code> code) OVERRIDE;
+ void FinishCode(Handle<Code> code) override;
- void PrintName(std::ostream& os) const OVERRIDE { // NOLINT
+ void PrintName(std::ostream& os) const override { // NOLINT
os << (type() == StackFrame::ENTRY ? "JSEntryStub"
: "JSConstructEntryStub");
}
@@ -1529,11 +1818,22 @@
minor_key_ = TypeBits::encode(type);
}
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
if (type() == READ_ELEMENT) {
return ArgumentsAccessReadDescriptor(isolate());
+ } else {
+ return ArgumentsAccessNewDescriptor(isolate());
}
- return ContextOnlyDescriptor(isolate());
+ }
+
+ static Type ComputeType(bool is_unmapped, bool has_duplicate_parameters) {
+ if (is_unmapped) {
+ return Type::NEW_STRICT;
+ } else if (has_duplicate_parameters) {
+ return Type::NEW_SLOPPY_SLOW;
+ } else {
+ return Type::NEW_SLOPPY_FAST;
+ }
}
private:
@@ -1544,7 +1844,7 @@
void GenerateNewSloppyFast(MacroAssembler* masm);
void GenerateNewSloppySlow(MacroAssembler* masm);
- void PrintName(std::ostream& os) const OVERRIDE; // NOLINT
+ void PrintName(std::ostream& os) const override; // NOLINT
class TypeBits : public BitField<Type, 0, 2> {};
@@ -1552,6 +1852,20 @@
};
+class RestParamAccessStub : public PlatformCodeStub {
+ public:
+ explicit RestParamAccessStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
+
+ private:
+ void GenerateNew(MacroAssembler* masm);
+
+ void PrintName(std::ostream& os) const override; // NOLINT
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(RestParamAccess);
+ DEFINE_PLATFORM_CODE_STUB(RestParamAccess, PlatformCodeStub);
+};
+
+
class RegExpExecStub: public PlatformCodeStub {
public:
explicit RegExpExecStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
@@ -1561,7 +1875,7 @@
};
-class RegExpConstructResultStub FINAL : public HydrogenCodeStub {
+class RegExpConstructResultStub final : public HydrogenCodeStub {
public:
explicit RegExpConstructResultStub(Isolate* isolate)
: HydrogenCodeStub(isolate) { }
@@ -1576,61 +1890,10 @@
};
-class CallFunctionStub: public PlatformCodeStub {
+// TODO(bmeurer/mvstanton): Turn CallConstructStub into ConstructICStub.
+class CallConstructStub final : public PlatformCodeStub {
public:
- CallFunctionStub(Isolate* isolate, int argc, CallFunctionFlags flags)
- : PlatformCodeStub(isolate) {
- DCHECK(argc >= 0 && argc <= Code::kMaxArguments);
- minor_key_ = ArgcBits::encode(argc) | FlagBits::encode(flags);
- }
-
- static int ExtractArgcFromMinorKey(int minor_key) {
- return ArgcBits::decode(minor_key);
- }
-
- private:
- int argc() const { return ArgcBits::decode(minor_key_); }
- int flags() const { return FlagBits::decode(minor_key_); }
-
- bool CallAsMethod() const {
- return flags() == CALL_AS_METHOD || flags() == WRAP_AND_CALL;
- }
-
- bool NeedsChecks() const { return flags() != WRAP_AND_CALL; }
-
- void PrintName(std::ostream& os) const OVERRIDE; // NOLINT
-
- // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
- class FlagBits : public BitField<CallFunctionFlags, 0, 2> {};
- class ArgcBits : public BitField<unsigned, 2, Code::kArgumentsBits> {};
- STATIC_ASSERT(Code::kArgumentsBits + 2 <= kStubMinorKeyBits);
-
- DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction);
- DEFINE_PLATFORM_CODE_STUB(CallFunction, PlatformCodeStub);
-};
-
-
-class CallConstructStub: public PlatformCodeStub {
- public:
- CallConstructStub(Isolate* isolate, CallConstructorFlags flags)
- : PlatformCodeStub(isolate) {
- minor_key_ = FlagBits::encode(flags);
- }
-
- void FinishCode(Handle<Code> code) OVERRIDE {
- code->set_has_function_cache(RecordCallTarget());
- }
-
- private:
- CallConstructorFlags flags() const { return FlagBits::decode(minor_key_); }
-
- bool RecordCallTarget() const {
- return (flags() & RECORD_CONSTRUCTOR_TARGET) != 0;
- }
-
- void PrintName(std::ostream& os) const OVERRIDE; // NOLINT
-
- class FlagBits : public BitField<CallConstructorFlags, 0, 1> {};
+ explicit CallConstructStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(CallConstruct);
DEFINE_PLATFORM_CODE_STUB(CallConstruct, PlatformCodeStub);
@@ -1657,6 +1920,15 @@
};
+enum EmbedMode {
+ // The code being generated is part of an IC handler, which may MISS
+ // to an IC in failure cases.
+ PART_OF_IC_HANDLER,
+
+ NOT_PART_OF_IC_HANDLER
+};
+
+
// Generates code implementing String.prototype.charCodeAt.
//
// Only supports the case when the receiver is a string and the index
@@ -1693,7 +1965,7 @@
// Generates the slow case code. Must not be naturally
// reachable. Expected to be put after a ret instruction (e.g., in
// deferred code). Always jumps back to the fast case.
- void GenerateSlow(MacroAssembler* masm,
+ void GenerateSlow(MacroAssembler* masm, EmbedMode embed_mode,
const RuntimeCallHelper& call_helper);
// Skip handling slow case and directly jump to bailout.
@@ -1793,9 +2065,9 @@
// Generates the slow case code. Must not be naturally
// reachable. Expected to be put after a ret instruction (e.g., in
// deferred code). Always jumps back to the fast case.
- void GenerateSlow(MacroAssembler* masm,
+ void GenerateSlow(MacroAssembler* masm, EmbedMode embed_mode,
const RuntimeCallHelper& call_helper) {
- char_code_at_generator_.GenerateSlow(masm, call_helper);
+ char_code_at_generator_.GenerateSlow(masm, embed_mode, call_helper);
char_from_code_generator_.GenerateSlow(masm, call_helper);
}
@@ -1815,14 +2087,17 @@
class LoadDictionaryElementStub : public HydrogenCodeStub {
public:
- explicit LoadDictionaryElementStub(Isolate* isolate)
- : HydrogenCodeStub(isolate) {}
+ explicit LoadDictionaryElementStub(Isolate* isolate, const LoadICState& state)
+ : HydrogenCodeStub(isolate) {
+ minor_key_ = state.GetExtraICState();
+ }
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
- if (FLAG_vector_ics) {
- return VectorLoadICDescriptor(isolate());
- }
- return LoadDescriptor(isolate());
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
+ return LoadWithVectorDescriptor(isolate());
+ }
+
+ LanguageMode language_mode() const {
+ return LoadICState::GetLanguageMode(MinorKey());
}
DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub);
@@ -1831,14 +2106,18 @@
class KeyedLoadGenericStub : public HydrogenCodeStub {
public:
- explicit KeyedLoadGenericStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
+ explicit KeyedLoadGenericStub(Isolate* isolate, const LoadICState& state)
+ : HydrogenCodeStub(isolate) {
+ minor_key_ = state.GetExtraICState();
+ }
- Code::Kind GetCodeKind() const OVERRIDE { return Code::KEYED_LOAD_IC; }
- InlineCacheState GetICState() const OVERRIDE { return GENERIC; }
+ Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
+ InlineCacheState GetICState() const override { return GENERIC; }
- // Since KeyedLoadGeneric stub doesn't miss (simply calls runtime), it
- // doesn't need to use the VectorLoadICDescriptor for the case when
- // flag --vector-ics is true.
+ LanguageMode language_mode() const {
+ return LoadICState::GetLanguageMode(MinorKey());
+ }
+
DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
DEFINE_HYDROGEN_CODE_STUB(KeyedLoadGeneric, HydrogenCodeStub);
@@ -1852,93 +2131,187 @@
minor_key_ = state.GetExtraICState();
}
- Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; }
+ Code::Kind GetCodeKind() const override { return Code::LOAD_IC; }
- InlineCacheState GetICState() const FINAL { return DEFAULT; }
+ InlineCacheState GetICState() const final { return GENERIC; }
- ExtraICState GetExtraICState() const FINAL {
+ ExtraICState GetExtraICState() const final {
return static_cast<ExtraICState>(minor_key_);
}
- private:
+ protected:
LoadICState state() const {
return LoadICState(static_cast<ExtraICState>(minor_key_));
}
- DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadICTrampoline);
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
DEFINE_PLATFORM_CODE_STUB(LoadICTrampoline, PlatformCodeStub);
};
class KeyedLoadICTrampolineStub : public LoadICTrampolineStub {
public:
- explicit KeyedLoadICTrampolineStub(Isolate* isolate)
- : LoadICTrampolineStub(isolate, LoadICState(0)) {}
+ explicit KeyedLoadICTrampolineStub(Isolate* isolate, const LoadICState& state)
+ : LoadICTrampolineStub(isolate, state) {}
- Code::Kind GetCodeKind() const OVERRIDE { return Code::KEYED_LOAD_IC; }
+ Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
DEFINE_PLATFORM_CODE_STUB(KeyedLoadICTrampoline, LoadICTrampolineStub);
};
-class MegamorphicLoadStub : public HydrogenCodeStub {
+class VectorStoreICTrampolineStub : public PlatformCodeStub {
public:
- MegamorphicLoadStub(Isolate* isolate, const LoadICState& state)
- : HydrogenCodeStub(isolate) {
- set_sub_minor_key(state.GetExtraICState());
+ VectorStoreICTrampolineStub(Isolate* isolate, const StoreICState& state)
+ : PlatformCodeStub(isolate) {
+ minor_key_ = state.GetExtraICState();
}
- Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; }
+ Code::Kind GetCodeKind() const override { return Code::STORE_IC; }
- InlineCacheState GetICState() const FINAL { return MEGAMORPHIC; }
+ InlineCacheState GetICState() const final { return GENERIC; }
- ExtraICState GetExtraICState() const FINAL {
- return static_cast<ExtraICState>(sub_minor_key());
+ ExtraICState GetExtraICState() const final {
+ return static_cast<ExtraICState>(minor_key_);
}
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
- if (FLAG_vector_ics) {
- return VectorLoadICDescriptor(isolate());
- }
- return LoadDescriptor(isolate());
- }
-
- DEFINE_HYDROGEN_CODE_STUB(MegamorphicLoad, HydrogenCodeStub);
-};
-
-
-class VectorLoadStub : public HydrogenCodeStub {
- public:
- explicit VectorLoadStub(Isolate* isolate, const LoadICState& state)
- : HydrogenCodeStub(isolate) {
- set_sub_minor_key(state.GetExtraICState());
- }
-
- Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; }
-
- InlineCacheState GetICState() const FINAL { return DEFAULT; }
-
- ExtraICState GetExtraICState() const FINAL {
- return static_cast<ExtraICState>(sub_minor_key());
+ protected:
+ StoreICState state() const {
+ return StoreICState(static_cast<ExtraICState>(minor_key_));
}
private:
- LoadICState state() const { return LoadICState(GetExtraICState()); }
-
- DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadIC);
- DEFINE_HYDROGEN_CODE_STUB(VectorLoad, HydrogenCodeStub);
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreICTrampoline);
+ DEFINE_PLATFORM_CODE_STUB(VectorStoreICTrampoline, PlatformCodeStub);
};
-class VectorKeyedLoadStub : public VectorLoadStub {
+class VectorKeyedStoreICTrampolineStub : public VectorStoreICTrampolineStub {
public:
- explicit VectorKeyedLoadStub(Isolate* isolate)
- : VectorLoadStub(isolate, LoadICState(0)) {}
+ VectorKeyedStoreICTrampolineStub(Isolate* isolate, const StoreICState& state)
+ : VectorStoreICTrampolineStub(isolate, state) {}
- Code::Kind GetCodeKind() const OVERRIDE { return Code::KEYED_LOAD_IC; }
+ Code::Kind GetCodeKind() const override { return Code::KEYED_STORE_IC; }
- DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadIC);
- DEFINE_HYDROGEN_CODE_STUB(VectorKeyedLoad, VectorLoadStub);
+ DEFINE_PLATFORM_CODE_STUB(VectorKeyedStoreICTrampoline,
+ VectorStoreICTrampolineStub);
+};
+
+
+class CallICTrampolineStub : public PlatformCodeStub {
+ public:
+ CallICTrampolineStub(Isolate* isolate, const CallICState& state)
+ : PlatformCodeStub(isolate) {
+ minor_key_ = state.GetExtraICState();
+ }
+
+ Code::Kind GetCodeKind() const override { return Code::CALL_IC; }
+
+ InlineCacheState GetICState() const final { return GENERIC; }
+
+ ExtraICState GetExtraICState() const final {
+ return static_cast<ExtraICState>(minor_key_);
+ }
+
+ protected:
+ CallICState state() const {
+ return CallICState(static_cast<ExtraICState>(minor_key_));
+ }
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback);
+ DEFINE_PLATFORM_CODE_STUB(CallICTrampoline, PlatformCodeStub);
+};
+
+
+class LoadICStub : public PlatformCodeStub {
+ public:
+ explicit LoadICStub(Isolate* isolate, const LoadICState& state)
+ : PlatformCodeStub(isolate) {
+ minor_key_ = state.GetExtraICState();
+ }
+
+ void GenerateForTrampoline(MacroAssembler* masm);
+
+ Code::Kind GetCodeKind() const override { return Code::LOAD_IC; }
+ InlineCacheState GetICState() const final { return GENERIC; }
+ ExtraICState GetExtraICState() const final {
+ return static_cast<ExtraICState>(minor_key_);
+ }
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
+ DEFINE_PLATFORM_CODE_STUB(LoadIC, PlatformCodeStub);
+
+ protected:
+ void GenerateImpl(MacroAssembler* masm, bool in_frame);
+};
+
+
+class KeyedLoadICStub : public PlatformCodeStub {
+ public:
+ explicit KeyedLoadICStub(Isolate* isolate, const LoadICState& state)
+ : PlatformCodeStub(isolate) {
+ minor_key_ = state.GetExtraICState();
+ }
+
+ void GenerateForTrampoline(MacroAssembler* masm);
+
+ Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
+ InlineCacheState GetICState() const final { return GENERIC; }
+ ExtraICState GetExtraICState() const final {
+ return static_cast<ExtraICState>(minor_key_);
+ }
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
+ DEFINE_PLATFORM_CODE_STUB(KeyedLoadIC, PlatformCodeStub);
+
+ protected:
+ void GenerateImpl(MacroAssembler* masm, bool in_frame);
+};
+
+
+class VectorStoreICStub : public PlatformCodeStub {
+ public:
+ VectorStoreICStub(Isolate* isolate, const StoreICState& state)
+ : PlatformCodeStub(isolate) {
+ minor_key_ = state.GetExtraICState();
+ }
+
+ void GenerateForTrampoline(MacroAssembler* masm);
+
+ Code::Kind GetCodeKind() const final { return Code::STORE_IC; }
+ InlineCacheState GetICState() const final { return GENERIC; }
+ ExtraICState GetExtraICState() const final {
+ return static_cast<ExtraICState>(minor_key_);
+ }
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreIC);
+ DEFINE_PLATFORM_CODE_STUB(VectorStoreIC, PlatformCodeStub);
+
+ protected:
+ void GenerateImpl(MacroAssembler* masm, bool in_frame);
+};
+
+
+class VectorKeyedStoreICStub : public PlatformCodeStub {
+ public:
+ VectorKeyedStoreICStub(Isolate* isolate, const StoreICState& state)
+ : PlatformCodeStub(isolate) {
+ minor_key_ = state.GetExtraICState();
+ }
+
+ void GenerateForTrampoline(MacroAssembler* masm);
+
+ Code::Kind GetCodeKind() const final { return Code::KEYED_STORE_IC; }
+ InlineCacheState GetICState() const final { return GENERIC; }
+ ExtraICState GetExtraICState() const final {
+ return static_cast<ExtraICState>(minor_key_);
+ }
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreIC);
+ DEFINE_PLATFORM_CODE_STUB(VectorKeyedStoreIC, PlatformCodeStub);
+
+ protected:
+ void GenerateImpl(MacroAssembler* masm, bool in_frame);
};
@@ -1955,7 +2328,7 @@
SSE3Bits::encode(CpuFeatures::IsSupported(SSE3) ? 1 : 0);
}
- bool SometimesSetsUpAFrame() OVERRIDE { return false; }
+ bool SometimesSetsUpAFrame() override { return false; }
private:
Register source() const {
@@ -1995,6 +2368,7 @@
const ScriptContextTable::LookupResult* lookup_result)
: HandlerStub(isolate) {
DCHECK(Accepted(lookup_result));
+ STATIC_ASSERT(kContextIndexBits + kSlotIndexBits <= kSubMinorKeyBits);
set_sub_minor_key(ContextIndexBits::encode(lookup_result->context_index) |
SlotIndexBits::encode(lookup_result->slot_index));
}
@@ -2011,13 +2385,13 @@
}
private:
- static const int kContextIndexBits = 13;
+ static const int kContextIndexBits = 9;
static const int kSlotIndexBits = 13;
class ContextIndexBits : public BitField<int, 0, kContextIndexBits> {};
class SlotIndexBits
: public BitField<int, kContextIndexBits, kSlotIndexBits> {};
- Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+ Code::StubType GetStubType() const override { return Code::FAST; }
DEFINE_CODE_STUB_BASE(ScriptContextFieldStub, HandlerStub);
};
@@ -2030,7 +2404,7 @@
: ScriptContextFieldStub(isolate, lookup_result) {}
private:
- Code::Kind kind() const OVERRIDE { return Code::LOAD_IC; }
+ Code::Kind kind() const override { return Code::LOAD_IC; }
DEFINE_HANDLER_CODE_STUB(LoadScriptContextField, ScriptContextFieldStub);
};
@@ -2043,22 +2417,30 @@
: ScriptContextFieldStub(isolate, lookup_result) {}
private:
- Code::Kind kind() const OVERRIDE { return Code::STORE_IC; }
+ Code::Kind kind() const override { return Code::STORE_IC; }
DEFINE_HANDLER_CODE_STUB(StoreScriptContextField, ScriptContextFieldStub);
};
-class LoadFastElementStub : public HydrogenCodeStub {
+class LoadFastElementStub : public HandlerStub {
public:
LoadFastElementStub(Isolate* isolate, bool is_js_array,
- ElementsKind elements_kind)
- : HydrogenCodeStub(isolate) {
- set_sub_minor_key(ElementsKindBits::encode(elements_kind) |
- IsJSArrayBits::encode(is_js_array));
+ ElementsKind elements_kind,
+ bool convert_hole_to_undefined = false)
+ : HandlerStub(isolate) {
+ set_sub_minor_key(
+ ElementsKindBits::encode(elements_kind) |
+ IsJSArrayBits::encode(is_js_array) |
+ CanConvertHoleToUndefined::encode(convert_hole_to_undefined));
}
+ Code::Kind kind() const override { return Code::KEYED_LOAD_IC; }
+
bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
+ bool convert_hole_to_undefined() const {
+ return CanConvertHoleToUndefined::decode(sub_minor_key());
+ }
ElementsKind elements_kind() const {
return ElementsKindBits::decode(sub_minor_key());
@@ -2067,15 +2449,9 @@
private:
class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
class IsJSArrayBits: public BitField<bool, 8, 1> {};
+ class CanConvertHoleToUndefined : public BitField<bool, 9, 1> {};
- CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
- if (FLAG_vector_ics) {
- return VectorLoadICDescriptor(isolate());
- }
- return LoadDescriptor(isolate());
- }
-
- DEFINE_HYDROGEN_CODE_STUB(LoadFastElement, HydrogenCodeStub);
+ DEFINE_HANDLER_CODE_STUB(LoadFastElement, HandlerStub);
};
@@ -2084,11 +2460,13 @@
StoreFastElementStub(Isolate* isolate, bool is_js_array,
ElementsKind elements_kind, KeyedAccessStoreMode mode)
: HydrogenCodeStub(isolate) {
- set_sub_minor_key(ElementsKindBits::encode(elements_kind) |
- IsJSArrayBits::encode(is_js_array) |
- StoreModeBits::encode(mode));
+ set_sub_minor_key(CommonStoreModeBits::encode(mode) |
+ ElementsKindBits::encode(elements_kind) |
+ IsJSArrayBits::encode(is_js_array));
}
+ static void GenerateAheadOfTime(Isolate* isolate);
+
bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
ElementsKind elements_kind() const {
@@ -2096,15 +2474,19 @@
}
KeyedAccessStoreMode store_mode() const {
- return StoreModeBits::decode(sub_minor_key());
+ return CommonStoreModeBits::decode(sub_minor_key());
}
- private:
- class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
- class StoreModeBits: public BitField<KeyedAccessStoreMode, 8, 4> {};
- class IsJSArrayBits: public BitField<bool, 12, 1> {};
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
+ return VectorStoreICDescriptor(isolate());
+ }
- DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
+ Code::Kind GetCodeKind() const override { return Code::HANDLER; }
+
+ private:
+ class ElementsKindBits : public BitField<ElementsKind, 3, 8> {};
+ class IsJSArrayBits : public BitField<bool, 11, 1> {};
+
DEFINE_HYDROGEN_CODE_STUB(StoreFastElement, HydrogenCodeStub);
};
@@ -2138,7 +2520,7 @@
};
-class AllocateHeapNumberStub FINAL : public HydrogenCodeStub {
+class AllocateHeapNumberStub final : public HydrogenCodeStub {
public:
explicit AllocateHeapNumberStub(Isolate* isolate)
: HydrogenCodeStub(isolate) {}
@@ -2149,6 +2531,28 @@
};
+class AllocateMutableHeapNumberStub final : public HydrogenCodeStub {
+ public:
+ explicit AllocateMutableHeapNumberStub(Isolate* isolate)
+ : HydrogenCodeStub(isolate) {}
+
+ private:
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateMutableHeapNumber);
+ DEFINE_HYDROGEN_CODE_STUB(AllocateMutableHeapNumber, HydrogenCodeStub);
+};
+
+
+class AllocateInNewSpaceStub final : public HydrogenCodeStub {
+ public:
+ explicit AllocateInNewSpaceStub(Isolate* isolate)
+ : HydrogenCodeStub(isolate) {}
+
+ private:
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateInNewSpace);
+ DEFINE_HYDROGEN_CODE_STUB(AllocateInNewSpace, HydrogenCodeStub);
+};
+
+
class ArrayConstructorStubBase : public HydrogenCodeStub {
public:
ArrayConstructorStubBase(Isolate* isolate,
@@ -2204,7 +2608,7 @@
}
private:
- void PrintName(std::ostream& os) const OVERRIDE { // NOLINT
+ void PrintName(std::ostream& os) const override { // NOLINT
BasePrintName(os, "ArrayNoArgumentConstructorStub");
}
@@ -2224,7 +2628,7 @@
}
private:
- void PrintName(std::ostream& os) const OVERRIDE { // NOLINT
+ void PrintName(std::ostream& os) const override { // NOLINT
BasePrintName(os, "ArraySingleArgumentConstructorStub");
}
@@ -2244,7 +2648,7 @@
}
private:
- void PrintName(std::ostream& os) const OVERRIDE { // NOLINT
+ void PrintName(std::ostream& os) const override { // NOLINT
BasePrintName(os, "ArrayNArgumentsConstructorStub");
}
@@ -2317,19 +2721,26 @@
class StoreElementStub : public PlatformCodeStub {
public:
- StoreElementStub(Isolate* isolate, ElementsKind elements_kind)
+ StoreElementStub(Isolate* isolate, ElementsKind elements_kind,
+ KeyedAccessStoreMode mode)
: PlatformCodeStub(isolate) {
- minor_key_ = ElementsKindBits::encode(elements_kind);
+ minor_key_ = ElementsKindBits::encode(elements_kind) |
+ CommonStoreModeBits::encode(mode);
}
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
+ return VectorStoreICDescriptor(isolate());
+ }
+
+ Code::Kind GetCodeKind() const override { return Code::HANDLER; }
+
private:
ElementsKind elements_kind() const {
return ElementsKindBits::decode(minor_key_);
}
- class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
+ class ElementsKindBits : public BitField<ElementsKind, 3, 8> {};
- DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
DEFINE_PLATFORM_CODE_STUB(StoreElement, PlatformCodeStub);
};
@@ -2345,61 +2756,49 @@
STRING,
SYMBOL,
HEAP_NUMBER,
+ SIMD_VALUE,
NUMBER_OF_TYPES
};
- enum ResultMode {
- RESULT_AS_SMI, // For Smi(1) on truthy value, Smi(0) otherwise.
- RESULT_AS_ODDBALL, // For {true} on truthy value, {false} otherwise.
- RESULT_AS_INVERSE_ODDBALL // For {false} on truthy value, {true} otherwise.
- };
+ // At most 16 different types can be distinguished, because the Code object
+ // only has room for two bytes to hold a set of these types. :-P
+ STATIC_ASSERT(NUMBER_OF_TYPES <= 16);
- // At most 8 different types can be distinguished, because the Code object
- // only has room for a single byte to hold a set of these types. :-P
- STATIC_ASSERT(NUMBER_OF_TYPES <= 8);
-
- class Types : public EnumSet<Type, byte> {
+ class Types : public EnumSet<Type, uint16_t> {
public:
- Types() : EnumSet<Type, byte>(0) {}
- explicit Types(byte bits) : EnumSet<Type, byte>(bits) {}
+ Types() : EnumSet<Type, uint16_t>(0) {}
+ explicit Types(uint16_t bits) : EnumSet<Type, uint16_t>(bits) {}
- byte ToByte() const { return ToIntegral(); }
bool UpdateStatus(Handle<Object> object);
bool NeedsMap() const;
- bool CanBeUndetectable() const;
+ bool CanBeUndetectable() const {
+ return Contains(ToBooleanStub::SPEC_OBJECT);
+ }
bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); }
static Types Generic() { return Types((1 << NUMBER_OF_TYPES) - 1); }
};
- ToBooleanStub(Isolate* isolate, ResultMode mode, Types types = Types())
- : HydrogenCodeStub(isolate) {
- set_sub_minor_key(TypesBits::encode(types.ToByte()) |
- ResultModeBits::encode(mode));
- }
-
ToBooleanStub(Isolate* isolate, ExtraICState state)
: HydrogenCodeStub(isolate) {
- set_sub_minor_key(TypesBits::encode(static_cast<byte>(state)) |
- ResultModeBits::encode(RESULT_AS_SMI));
+ set_sub_minor_key(TypesBits::encode(static_cast<uint16_t>(state)));
}
bool UpdateStatus(Handle<Object> object);
Types types() const { return Types(TypesBits::decode(sub_minor_key())); }
- ResultMode mode() const { return ResultModeBits::decode(sub_minor_key()); }
- Code::Kind GetCodeKind() const OVERRIDE { return Code::TO_BOOLEAN_IC; }
- void PrintState(std::ostream& os) const OVERRIDE; // NOLINT
+ Code::Kind GetCodeKind() const override { return Code::TO_BOOLEAN_IC; }
+ void PrintState(std::ostream& os) const override; // NOLINT
- bool SometimesSetsUpAFrame() OVERRIDE { return false; }
+ bool SometimesSetsUpAFrame() override { return false; }
static Handle<Code> GetUninitialized(Isolate* isolate) {
return ToBooleanStub(isolate, UNINITIALIZED).GetCode();
}
- ExtraICState GetExtraICState() const OVERRIDE { return types().ToIntegral(); }
+ ExtraICState GetExtraICState() const override { return types().ToIntegral(); }
- InlineCacheState GetICState() const OVERRIDE {
+ InlineCacheState GetICState() const override {
if (types().IsEmpty()) {
return ::v8::internal::UNINITIALIZED;
} else {
@@ -2410,11 +2809,9 @@
private:
ToBooleanStub(Isolate* isolate, InitializationState init_state)
: HydrogenCodeStub(isolate, init_state) {
- set_sub_minor_key(ResultModeBits::encode(RESULT_AS_SMI));
}
- class TypesBits : public BitField<byte, 0, NUMBER_OF_TYPES> {};
- class ResultModeBits : public BitField<ResultMode, NUMBER_OF_TYPES, 2> {};
+ class TypesBits : public BitField<uint16_t, 0, NUMBER_OF_TYPES> {};
DEFINE_CALL_INTERFACE_DESCRIPTOR(ToBoolean);
DEFINE_HYDROGEN_CODE_STUB(ToBoolean, HydrogenCodeStub);
@@ -2430,61 +2827,30 @@
ElementsKind to_kind, bool is_jsarray,
KeyedAccessStoreMode store_mode)
: HydrogenCodeStub(isolate) {
- set_sub_minor_key(FromBits::encode(from_kind) | ToBits::encode(to_kind) |
- IsJSArrayBits::encode(is_jsarray) |
- StoreModeBits::encode(store_mode));
+ set_sub_minor_key(CommonStoreModeBits::encode(store_mode) |
+ FromBits::encode(from_kind) | ToBits::encode(to_kind) |
+ IsJSArrayBits::encode(is_jsarray));
}
ElementsKind from_kind() const { return FromBits::decode(sub_minor_key()); }
ElementsKind to_kind() const { return ToBits::decode(sub_minor_key()); }
bool is_jsarray() const { return IsJSArrayBits::decode(sub_minor_key()); }
KeyedAccessStoreMode store_mode() const {
- return StoreModeBits::decode(sub_minor_key());
+ return CommonStoreModeBits::decode(sub_minor_key());
}
- // Parameters accessed via CodeStubGraphBuilder::GetParameter()
- enum ParameterIndices {
- kValueIndex,
- kMapIndex,
- kKeyIndex,
- kObjectIndex,
- kParameterCount
- };
-
- static const Register ValueRegister() {
- return ElementTransitionAndStoreDescriptor::ValueRegister();
- }
- static const Register MapRegister() {
- return ElementTransitionAndStoreDescriptor::MapRegister();
- }
- static const Register KeyRegister() {
- return ElementTransitionAndStoreDescriptor::NameRegister();
- }
- static const Register ObjectRegister() {
- return ElementTransitionAndStoreDescriptor::ReceiverRegister();
- }
+ CallInterfaceDescriptor GetCallInterfaceDescriptor() const override;
+ Code::Kind GetCodeKind() const override { return Code::HANDLER; }
private:
- class FromBits : public BitField<ElementsKind, 0, 8> {};
- class ToBits : public BitField<ElementsKind, 8, 8> {};
- class IsJSArrayBits : public BitField<bool, 16, 1> {};
- class StoreModeBits : public BitField<KeyedAccessStoreMode, 17, 4> {};
+ class FromBits : public BitField<ElementsKind, 3, 8> {};
+ class ToBits : public BitField<ElementsKind, 11, 8> {};
+ class IsJSArrayBits : public BitField<bool, 19, 1> {};
- DEFINE_CALL_INTERFACE_DESCRIPTOR(ElementTransitionAndStore);
DEFINE_HYDROGEN_CODE_STUB(ElementsTransitionAndStore, HydrogenCodeStub);
};
-class StoreArrayLiteralElementStub : public PlatformCodeStub {
- public:
- explicit StoreArrayLiteralElementStub(Isolate* isolate)
- : PlatformCodeStub(isolate) { }
-
- DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreArrayLiteralElement);
- DEFINE_PLATFORM_CODE_STUB(StoreArrayLiteralElement, PlatformCodeStub);
-};
-
-
class StubFailureTrampolineStub : public PlatformCodeStub {
public:
StubFailureTrampolineStub(Isolate* isolate, StubFunctionMode function_mode)
@@ -2511,7 +2877,7 @@
explicit ProfileEntryHookStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
// The profile entry hook function is not allowed to cause a GC.
- bool SometimesSetsUpAFrame() OVERRIDE { return false; }
+ bool SometimesSetsUpAFrame() override { return false; }
// Generates a call to the entry hook if it's enabled.
static void MaybeCallEntryHook(MacroAssembler* masm);
@@ -2536,7 +2902,7 @@
}
static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
- bool SometimesSetsUpAFrame() OVERRIDE { return false; }
+ bool SometimesSetsUpAFrame() override { return false; }
private:
bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
@@ -2557,7 +2923,7 @@
};
-class ToNumberStub FINAL : public PlatformCodeStub {
+class ToNumberStub final : public PlatformCodeStub {
public:
explicit ToNumberStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
@@ -2566,11 +2932,38 @@
};
+class ToLengthStub final : public PlatformCodeStub {
+ public:
+ explicit ToLengthStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(ToLength);
+ DEFINE_PLATFORM_CODE_STUB(ToLength, PlatformCodeStub);
+};
+
+
+class ToStringStub final : public PlatformCodeStub {
+ public:
+ explicit ToStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(ToString);
+ DEFINE_PLATFORM_CODE_STUB(ToString, PlatformCodeStub);
+};
+
+
+class ToObjectStub final : public HydrogenCodeStub {
+ public:
+ explicit ToObjectStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
+
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(ToObject);
+ DEFINE_HYDROGEN_CODE_STUB(ToObject, HydrogenCodeStub);
+};
+
+
class StringCompareStub : public PlatformCodeStub {
public:
explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
- DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(StringCompare);
DEFINE_PLATFORM_CODE_STUB(StringCompare, PlatformCodeStub);
};
@@ -2581,6 +2974,10 @@
#undef DEFINE_HYDROGEN_CODE_STUB
#undef DEFINE_CODE_STUB
#undef DEFINE_CODE_STUB_BASE
-} } // namespace v8::internal
+
+extern Representation RepresentationFromType(Type* type);
+
+} // namespace internal
+} // namespace v8
#endif // V8_CODE_STUBS_H_