| Index: src/code-stubs.h
|
| diff --git a/src/code-stubs.h b/src/code-stubs.h
|
| index 80d99d8b689f704ce475f3d96a2978ae2e339631..8f1b686743317a39f95b764933a901de4b788214 100644
|
| --- a/src/code-stubs.h
|
| +++ b/src/code-stubs.h
|
| @@ -43,6 +43,7 @@ namespace internal {
|
| V(CallConstruct) \
|
| V(BinaryOp) \
|
| V(StringAdd) \
|
| + V(NewStringAdd) \
|
| V(SubString) \
|
| V(StringCompare) \
|
| V(Compare) \
|
| @@ -276,23 +277,23 @@ class PlatformCodeStub : public CodeStub {
|
|
|
|
|
| enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
|
| -
|
| +enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS };
|
|
|
| struct CodeStubInterfaceDescriptor {
|
| CodeStubInterfaceDescriptor();
|
| int register_param_count_;
|
| +
|
| Register stack_parameter_count_;
|
| // 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_;
|
| StubFunctionMode function_mode_;
|
| Register* register_params_;
|
| +
|
| Address deoptimization_handler_;
|
| + HandlerArgumentsMode handler_arguments_mode_;
|
|
|
| int environment_length() const {
|
| - if (stack_parameter_count_.is_valid()) {
|
| - return register_param_count_ + 1;
|
| - }
|
| return register_param_count_;
|
| }
|
|
|
| @@ -301,6 +302,9 @@ struct CodeStubInterfaceDescriptor {
|
| void SetMissHandler(ExternalReference handler) {
|
| miss_handler_ = handler;
|
| has_miss_handler_ = true;
|
| + // Our miss handler infrastructure doesn't currently support
|
| + // variable stack parameter counts.
|
| + ASSERT(!stack_parameter_count_.is_valid());
|
| }
|
|
|
| ExternalReference miss_handler() {
|
| @@ -312,18 +316,27 @@ struct CodeStubInterfaceDescriptor {
|
| return has_miss_handler_;
|
| }
|
|
|
| + Register GetParameterRegister(int index) {
|
| + return register_params_[index];
|
| + }
|
| +
|
| + bool IsParameterCountRegister(int index) {
|
| + return GetParameterRegister(index).is(stack_parameter_count_);
|
| + }
|
| +
|
| + int GetHandlerParameterCount() {
|
| + int params = environment_length();
|
| + if (handler_arguments_mode_ == PASS_ARGUMENTS) {
|
| + params += 1;
|
| + }
|
| + return params;
|
| + }
|
| +
|
| private:
|
| ExternalReference miss_handler_;
|
| bool has_miss_handler_;
|
| };
|
|
|
| -// A helper to make up for the fact that type Register is not fully
|
| -// defined outside of the platform directories
|
| -#define DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index) \
|
| - ((index) == (descriptor)->register_param_count_) \
|
| - ? (descriptor)->stack_parameter_count_ \
|
| - : (descriptor)->register_params_[(index)]
|
| -
|
|
|
| class HydrogenCodeStub : public CodeStub {
|
| public:
|
| @@ -553,51 +566,6 @@ class FastNewBlockContextStub : public PlatformCodeStub {
|
| int MinorKey() { return slots_; }
|
| };
|
|
|
| -class StoreGlobalStub : public HydrogenCodeStub {
|
| - public:
|
| - StoreGlobalStub(StrictModeFlag strict_mode, bool is_constant) {
|
| - bit_field_ = StrictModeBits::encode(strict_mode) |
|
| - IsConstantBits::encode(is_constant);
|
| - }
|
| -
|
| - virtual Handle<Code> GenerateCode(Isolate* isolate);
|
| -
|
| - virtual void InitializeInterfaceDescriptor(
|
| - Isolate* isolate,
|
| - CodeStubInterfaceDescriptor* descriptor);
|
| -
|
| - virtual Code::Kind GetCodeKind() const { return Code::STORE_IC; }
|
| - virtual InlineCacheState GetICState() { return MONOMORPHIC; }
|
| - virtual Code::ExtraICState GetExtraICState() { return bit_field_; }
|
| -
|
| - bool is_constant() {
|
| - return IsConstantBits::decode(bit_field_);
|
| - }
|
| - void set_is_constant(bool value) {
|
| - bit_field_ = IsConstantBits::update(bit_field_, value);
|
| - }
|
| -
|
| - Representation representation() {
|
| - return Representation::FromKind(RepresentationBits::decode(bit_field_));
|
| - }
|
| - void set_representation(Representation r) {
|
| - bit_field_ = RepresentationBits::update(bit_field_, r.kind());
|
| - }
|
| -
|
| - private:
|
| - virtual int NotMissMinorKey() { return GetExtraICState(); }
|
| - Major MajorKey() { return StoreGlobal; }
|
| -
|
| - class StrictModeBits: public BitField<StrictModeFlag, 0, 1> {};
|
| - class IsConstantBits: public BitField<bool, 1, 1> {};
|
| - class RepresentationBits: public BitField<Representation::Kind, 2, 8> {};
|
| -
|
| - int bit_field_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub);
|
| -};
|
| -
|
| -
|
| class FastCloneShallowArrayStub : public HydrogenCodeStub {
|
| public:
|
| // Maximum length of copied elements array.
|
| @@ -899,7 +867,6 @@ class HICStub: public HydrogenCodeStub {
|
| virtual InlineCacheState GetICState() { return MONOMORPHIC; }
|
|
|
| protected:
|
| - HICStub() { }
|
| class KindBits: public BitField<Code::Kind, 0, 4> {};
|
| virtual Code::Kind kind() const = 0;
|
| };
|
| @@ -909,16 +876,12 @@ class HandlerStub: public HICStub {
|
| public:
|
| virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
|
| virtual int GetStubFlags() { return kind(); }
|
| -
|
| - protected:
|
| - HandlerStub() : HICStub() { }
|
| };
|
|
|
|
|
| class LoadFieldStub: public HandlerStub {
|
| public:
|
| - LoadFieldStub(bool inobject, int index, Representation representation)
|
| - : HandlerStub() {
|
| + LoadFieldStub(bool inobject, int index, Representation representation) {
|
| Initialize(Code::LOAD_IC, inobject, index, representation);
|
| }
|
|
|
| @@ -980,6 +943,63 @@ class LoadFieldStub: public HandlerStub {
|
| };
|
|
|
|
|
| +class StoreGlobalStub : public HandlerStub {
|
| + public:
|
| + StoreGlobalStub(StrictModeFlag strict_mode, bool is_constant) {
|
| + bit_field_ = StrictModeBits::encode(strict_mode) |
|
| + IsConstantBits::encode(is_constant);
|
| + }
|
| +
|
| + Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate,
|
| + Map* receiver_map,
|
| + PropertyCell* cell) {
|
| + Handle<Code> code = CodeStub::GetCodeCopyFromTemplate(isolate);
|
| + // Replace the placeholder cell and global object map with the actual global
|
| + // cell and receiver map.
|
| + Map* cell_map = isolate->heap()->global_property_cell_map();
|
| + code->ReplaceNthObject(1, cell_map, cell);
|
| + code->ReplaceNthObject(1, isolate->heap()->meta_map(), receiver_map);
|
| + return code;
|
| + }
|
| +
|
| + virtual Code::Kind kind() const { return Code::STORE_IC; }
|
| +
|
| + virtual Handle<Code> GenerateCode(Isolate* isolate);
|
| +
|
| + virtual void InitializeInterfaceDescriptor(
|
| + Isolate* isolate,
|
| + CodeStubInterfaceDescriptor* descriptor);
|
| +
|
| + virtual Code::ExtraICState GetExtraICState() { return bit_field_; }
|
| +
|
| + bool is_constant() {
|
| + return IsConstantBits::decode(bit_field_);
|
| + }
|
| + void set_is_constant(bool value) {
|
| + bit_field_ = IsConstantBits::update(bit_field_, value);
|
| + }
|
| +
|
| + Representation representation() {
|
| + return Representation::FromKind(RepresentationBits::decode(bit_field_));
|
| + }
|
| + void set_representation(Representation r) {
|
| + bit_field_ = RepresentationBits::update(bit_field_, r.kind());
|
| + }
|
| +
|
| + private:
|
| + virtual int NotMissMinorKey() { return GetExtraICState(); }
|
| + Major MajorKey() { return StoreGlobal; }
|
| +
|
| + class StrictModeBits: public BitField<StrictModeFlag, 0, 1> {};
|
| + class IsConstantBits: public BitField<bool, 1, 1> {};
|
| + class RepresentationBits: public BitField<Representation::Kind, 2, 8> {};
|
| +
|
| + int bit_field_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub);
|
| +};
|
| +
|
| +
|
| class KeyedLoadFieldStub: public LoadFieldStub {
|
| public:
|
| KeyedLoadFieldStub(bool inobject, int index, Representation representation)
|
| @@ -1172,6 +1192,47 @@ class BinaryOpStub: public HydrogenCodeStub {
|
| };
|
|
|
|
|
| +// TODO(bmeurer): Rename to StringAddStub once we dropped the old StringAddStub.
|
| +class NewStringAddStub V8_FINAL : public HydrogenCodeStub {
|
| + public:
|
| + NewStringAddStub(StringAddFlags flags, PretenureFlag pretenure_flag)
|
| + : bit_field_(StringAddFlagsBits::encode(flags) |
|
| + PretenureFlagBits::encode(pretenure_flag)) {}
|
| +
|
| + StringAddFlags flags() const {
|
| + return StringAddFlagsBits::decode(bit_field_);
|
| + }
|
| +
|
| + PretenureFlag pretenure_flag() const {
|
| + return PretenureFlagBits::decode(bit_field_);
|
| + }
|
| +
|
| + virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
|
| +
|
| + virtual void InitializeInterfaceDescriptor(
|
| + Isolate* isolate,
|
| + CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
|
| +
|
| + static void InstallDescriptors(Isolate* isolate);
|
| +
|
| + // Parameters accessed via CodeStubGraphBuilder::GetParameter()
|
| + static const int kLeft = 0;
|
| + static const int kRight = 1;
|
| +
|
| + private:
|
| + class StringAddFlagsBits: public BitField<StringAddFlags, 0, 2> {};
|
| + class PretenureFlagBits: public BitField<PretenureFlag, 2, 1> {};
|
| + uint32_t bit_field_;
|
| +
|
| + virtual Major MajorKey() V8_OVERRIDE { return NewStringAdd; }
|
| + virtual int NotMissMinorKey() V8_OVERRIDE { return bit_field_; }
|
| +
|
| + virtual void PrintBaseName(StringStream* stream) V8_OVERRIDE;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(NewStringAddStub);
|
| +};
|
| +
|
| +
|
| class ICCompareStub: public PlatformCodeStub {
|
| public:
|
| ICCompareStub(Token::Value op,
|
|
|