Revision f230a1cf deps/v8/src/code-stubs.h

View differences:

deps/v8/src/code-stubs.h
30 30

  
31 31
#include "allocation.h"
32 32
#include "assembler.h"
33
#include "globals.h"
34 33
#include "codegen.h"
34
#include "globals.h"
35
#include "macro-assembler.h"
35 36

  
36 37
namespace v8 {
37 38
namespace internal {
......
200 201

  
201 202
  virtual void PrintName(StringStream* stream);
202 203

  
204
  // Returns a name for logging/debugging purposes.
205
  SmartArrayPointer<const char> GetName();
206

  
203 207
 protected:
204 208
  static bool CanUseFPRegisters();
205 209

  
206 210
  // Generates the assembler code for the stub.
207 211
  virtual Handle<Code> GenerateCode(Isolate* isolate) = 0;
208 212

  
213
  virtual void VerifyPlatformFeatures(Isolate* isolate);
209 214

  
210 215
  // Returns whether the code generated for this stub needs to be allocated as
211 216
  // a fixed (non-moveable) code object.
212 217
  virtual bool NeedsImmovableCode() { return false; }
213 218

  
214
  // Returns a name for logging/debugging purposes.
215
  SmartArrayPointer<const char> GetName();
216 219
  virtual void PrintBaseName(StringStream* stream);
217 220
  virtual void PrintState(StringStream* stream) { }
218 221

  
......
278 281
struct CodeStubInterfaceDescriptor {
279 282
  CodeStubInterfaceDescriptor();
280 283
  int register_param_count_;
281
  const Register* stack_parameter_count_;
284
  Register stack_parameter_count_;
282 285
  // if hint_stack_parameter_count_ > 0, the code stub can optimize the
283 286
  // return sequence. Default value is -1, which means it is ignored.
284 287
  int hint_stack_parameter_count_;
......
287 290
  Address deoptimization_handler_;
288 291

  
289 292
  int environment_length() const {
290
    if (stack_parameter_count_ != NULL) {
293
    if (stack_parameter_count_.is_valid()) {
291 294
      return register_param_count_ + 1;
292 295
    }
293 296
    return register_param_count_;
......
318 321
// defined outside of the platform directories
319 322
#define DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index) \
320 323
  ((index) == (descriptor)->register_param_count_)           \
321
      ? *((descriptor)->stack_parameter_count_)              \
324
      ? (descriptor)->stack_parameter_count_                 \
322 325
      : (descriptor)->register_params_[(index)]
323 326

  
324 327

  
......
402 405
  // Check right parameter.
403 406
  STRING_ADD_CHECK_RIGHT = 1 << 1,
404 407
  // Check both parameters.
405
  STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT,
406
  // Stub needs a frame before calling the runtime
407
  STRING_ADD_ERECT_FRAME = 1 << 2
408
  STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT
408 409
};
409 410

  
410 411
} }  // namespace v8::internal
......
464 465
};
465 466

  
466 467

  
468
class NumberToStringStub V8_FINAL : public HydrogenCodeStub {
469
 public:
470
  NumberToStringStub() {}
471

  
472
  virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
473

  
474
  virtual void InitializeInterfaceDescriptor(
475
      Isolate* isolate,
476
      CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
477

  
478
  static void InstallDescriptors(Isolate* isolate);
479

  
480
  // Parameters accessed via CodeStubGraphBuilder::GetParameter()
481
  static const int kNumber = 0;
482

  
483
 private:
484
  virtual Major MajorKey() V8_OVERRIDE { return NumberToString; }
485
  virtual int NotMissMinorKey() V8_OVERRIDE { return 0; }
486
};
487

  
488

  
467 489
class FastNewClosureStub : public HydrogenCodeStub {
468 490
 public:
469 491
  explicit FastNewClosureStub(LanguageMode language_mode, bool is_generator)
......
830 852

  
831 853
class StringLengthStub: public ICStub {
832 854
 public:
833
  StringLengthStub(Code::Kind kind, bool support_wrapper)
834
      : ICStub(kind), support_wrapper_(support_wrapper) { }
855
  explicit StringLengthStub(Code::Kind kind) : ICStub(kind) { }
835 856
  virtual void Generate(MacroAssembler* masm);
836 857

  
837 858
 private:
838 859
  STATIC_ASSERT(KindBits::kSize == 4);
839
  class WrapperModeBits: public BitField<bool, 4, 1> {};
840
  virtual CodeStub::Major MajorKey() { return StringLength; }
841
  virtual int MinorKey() {
842
    return KindBits::encode(kind()) | WrapperModeBits::encode(support_wrapper_);
843
  }
844

  
845
  bool support_wrapper_;
860
    virtual CodeStub::Major MajorKey() { return StringLength; }
846 861
};
847 862

  
848 863

  
......
892 907

  
893 908
class HandlerStub: public HICStub {
894 909
 public:
895
  virtual Code::Kind GetCodeKind() const { return Code::STUB; }
910
  virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
896 911
  virtual int GetStubFlags() { return kind(); }
897 912

  
898 913
 protected:
......
983 998
};
984 999

  
985 1000

  
986
class BinaryOpStub: public PlatformCodeStub {
1001
class BinaryOpStub: public HydrogenCodeStub {
987 1002
 public:
988 1003
  BinaryOpStub(Token::Value op, OverwriteMode mode)
989
      : op_(op),
990
        mode_(mode),
991
        platform_specific_bit_(false),
992
        left_type_(BinaryOpIC::UNINITIALIZED),
993
        right_type_(BinaryOpIC::UNINITIALIZED),
994
        result_type_(BinaryOpIC::UNINITIALIZED),
995
        encoded_right_arg_(false, encode_arg_value(1)) {
1004
      : HydrogenCodeStub(UNINITIALIZED), op_(op), mode_(mode) {
1005
    ASSERT(op <= LAST_TOKEN && op >= FIRST_TOKEN);
996 1006
    Initialize();
997
    ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
998 1007
  }
999 1008

  
1000
  BinaryOpStub(
1001
      int key,
1002
      BinaryOpIC::TypeInfo left_type,
1003
      BinaryOpIC::TypeInfo right_type,
1004
      BinaryOpIC::TypeInfo result_type,
1005
      Maybe<int32_t> fixed_right_arg)
1006
      : op_(OpBits::decode(key)),
1007
        mode_(ModeBits::decode(key)),
1008
        platform_specific_bit_(PlatformSpecificBits::decode(key)),
1009
        left_type_(left_type),
1010
        right_type_(right_type),
1011
        result_type_(result_type),
1012
        encoded_right_arg_(fixed_right_arg.has_value,
1013
                           encode_arg_value(fixed_right_arg.value)) { }
1009
  explicit BinaryOpStub(Code::ExtraICState state)
1010
      : op_(decode_token(OpBits::decode(state))),
1011
        mode_(OverwriteModeField::decode(state)),
1012
        fixed_right_arg_(
1013
            Maybe<int>(HasFixedRightArgBits::decode(state),
1014
                decode_arg_value(FixedRightArgValueBits::decode(state)))),
1015
        left_state_(LeftStateField::decode(state)),
1016
        right_state_(fixed_right_arg_.has_value
1017
            ? ((fixed_right_arg_.value <= Smi::kMaxValue) ? SMI : INT32)
1018
            : RightStateField::decode(state)),
1019
        result_state_(ResultStateField::decode(state)) {
1020
    // We don't deserialize the SSE2 Field, since this is only used to be able
1021
    // to include SSE2 as well as non-SSE2 versions in the snapshot. For code
1022
    // generation we always want it to reflect the current state.
1023
    ASSERT(!fixed_right_arg_.has_value ||
1024
           can_encode_arg_value(fixed_right_arg_.value));
1025
  }
1026

  
1027
  static const int FIRST_TOKEN = Token::BIT_OR;
1028
  static const int LAST_TOKEN = Token::MOD;
1014 1029

  
1015
  static void decode_types_from_minor_key(int minor_key,
1016
                                          BinaryOpIC::TypeInfo* left_type,
1017
                                          BinaryOpIC::TypeInfo* right_type,
1018
                                          BinaryOpIC::TypeInfo* result_type) {
1019
    *left_type =
1020
        static_cast<BinaryOpIC::TypeInfo>(LeftTypeBits::decode(minor_key));
1021
    *right_type =
1022
        static_cast<BinaryOpIC::TypeInfo>(RightTypeBits::decode(minor_key));
1023
    *result_type =
1024
        static_cast<BinaryOpIC::TypeInfo>(ResultTypeBits::decode(minor_key));
1030
  static void GenerateAheadOfTime(Isolate* isolate);
1031
  virtual void InitializeInterfaceDescriptor(
1032
      Isolate* isolate, CodeStubInterfaceDescriptor* descriptor);
1033
  static void InitializeForIsolate(Isolate* isolate) {
1034
    BinaryOpStub binopStub(UNINITIALIZED);
1035
    binopStub.InitializeInterfaceDescriptor(
1036
        isolate, isolate->code_stub_interface_descriptor(CodeStub::BinaryOp));
1037
  }
1038

  
1039
  virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; }
1040
  virtual InlineCacheState GetICState() {
1041
    if (Max(left_state_, right_state_) == NONE) {
1042
      return ::v8::internal::UNINITIALIZED;
1043
    }
1044
    if (Max(left_state_, right_state_) == GENERIC) return MEGAMORPHIC;
1045
    return MONOMORPHIC;
1025 1046
  }
1026 1047

  
1027
  static Token::Value decode_op_from_minor_key(int minor_key) {
1028
    return static_cast<Token::Value>(OpBits::decode(minor_key));
1048
  virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
1049
    ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
1029 1050
  }
1030 1051

  
1031
  static Maybe<int> decode_fixed_right_arg_from_minor_key(int minor_key) {
1032
    return Maybe<int>(
1033
        HasFixedRightArgBits::decode(minor_key),
1034
        decode_arg_value(FixedRightArgValueBits::decode(minor_key)));
1052
  virtual Code::ExtraICState GetExtraICState() {
1053
    bool sse_field = Max(result_state_, Max(left_state_, right_state_)) > SMI &&
1054
                     CpuFeatures::IsSafeForSnapshot(SSE2);
1055

  
1056
    return OpBits::encode(encode_token(op_))
1057
         | LeftStateField::encode(left_state_)
1058
         | RightStateField::encode(fixed_right_arg_.has_value
1059
                                       ? NONE : right_state_)
1060
         | ResultStateField::encode(result_state_)
1061
         | HasFixedRightArgBits::encode(fixed_right_arg_.has_value)
1062
         | FixedRightArgValueBits::encode(fixed_right_arg_.has_value
1063
                                              ? encode_arg_value(
1064
                                                  fixed_right_arg_.value)
1065
                                              : 0)
1066
         | SSE2Field::encode(sse_field)
1067
         | OverwriteModeField::encode(mode_);
1035 1068
  }
1036 1069

  
1037
  int fixed_right_arg_value() const {
1038
    return decode_arg_value(encoded_right_arg_.value);
1070
  bool CanReuseDoubleBox() {
1071
    return result_state_ <= NUMBER && result_state_ > SMI &&
1072
      ((left_state_ > SMI && left_state_ <= NUMBER &&
1073
        mode_ == OVERWRITE_LEFT) ||
1074
       (right_state_ > SMI && right_state_ <= NUMBER &&
1075
        mode_ == OVERWRITE_RIGHT));
1039 1076
  }
1040 1077

  
1041
  static bool can_encode_arg_value(int32_t value) {
1042
    return value > 0 &&
1043
        IsPowerOf2(value) &&
1044
        FixedRightArgValueBits::is_valid(WhichPowerOf2(value));
1078
  bool HasSideEffects(Isolate* isolate) const {
1079
    Handle<Type> left = GetLeftType(isolate);
1080
    Handle<Type> right = GetRightType(isolate);
1081
    return left->Maybe(Type::Receiver()) || right->Maybe(Type::Receiver());
1045 1082
  }
1046 1083

  
1047
  enum SmiCodeGenerateHeapNumberResults {
1048
    ALLOW_HEAPNUMBER_RESULTS,
1049
    NO_HEAPNUMBER_RESULTS
1050
  };
1084
  virtual Handle<Code> GenerateCode(Isolate* isolate);
1051 1085

  
1052
 private:
1053
  Token::Value op_;
1054
  OverwriteMode mode_;
1055
  bool platform_specific_bit_;  // Indicates SSE3 on IA32.
1086
  Maybe<Handle<Object> > Result(Handle<Object> left,
1087
                         Handle<Object> right,
1088
                         Isolate* isolate);
1056 1089

  
1057
  // Operand type information determined at runtime.
1058
  BinaryOpIC::TypeInfo left_type_;
1059
  BinaryOpIC::TypeInfo right_type_;
1060
  BinaryOpIC::TypeInfo result_type_;
1090
  Token::Value operation() const { return op_; }
1091
  OverwriteMode mode() const { return mode_; }
1092
  Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
1061 1093

  
1062
  Maybe<int> encoded_right_arg_;
1094
  Handle<Type> GetLeftType(Isolate* isolate) const;
1095
  Handle<Type> GetRightType(Isolate* isolate) const;
1096
  Handle<Type> GetResultType(Isolate* isolate) const;
1063 1097

  
1064
  static int encode_arg_value(int32_t value) {
1065
    ASSERT(can_encode_arg_value(value));
1066
    return WhichPowerOf2(value);
1067
  }
1098
  void UpdateStatus(Handle<Object> left,
1099
                    Handle<Object> right,
1100
                    Maybe<Handle<Object> > result);
1068 1101

  
1069
  static int32_t decode_arg_value(int value) {
1070
    return 1 << value;
1102
  void PrintState(StringStream* stream);
1103

  
1104
 private:
1105
  explicit BinaryOpStub(InitializationState state) : HydrogenCodeStub(state),
1106
                                                     op_(Token::ADD),
1107
                                                     mode_(NO_OVERWRITE) {
1108
    Initialize();
1071 1109
  }
1110
  void Initialize();
1072 1111

  
1073
  virtual void PrintName(StringStream* stream);
1112
  enum State { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
1113

  
1114
  // We truncate the last bit of the token.
1115
  STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 5));
1116
  class LeftStateField:         public BitField<State, 0,  3> {};
1117
  // When fixed right arg is set, we don't need to store the right state.
1118
  // Thus the two fields can overlap.
1119
  class HasFixedRightArgBits:   public BitField<bool, 4, 1> {};
1120
  class FixedRightArgValueBits: public BitField<int,  5, 4> {};
1121
  class RightStateField:        public BitField<State, 5, 3> {};
1122
  class ResultStateField:       public BitField<State, 9, 3> {};
1123
  class SSE2Field:              public BitField<bool, 12, 1> {};
1124
  class OverwriteModeField:     public BitField<OverwriteMode, 13, 2> {};
1125
  class OpBits:                 public BitField<int, 15,  5> {};
1126

  
1127
  virtual CodeStub::Major MajorKey() { return BinaryOp; }
1128
  virtual int NotMissMinorKey() { return GetExtraICState(); }
1074 1129

  
1075
  // Minor key encoding in all 25 bits FFFFFHTTTRRRLLLPOOOOOOOMM.
1076
  // Note: We actually do not need 7 bits for the operation, just 4 bits to
1077
  // encode ADD, SUB, MUL, DIV, MOD, BIT_OR, BIT_AND, BIT_XOR, SAR, SHL, SHR.
1078
  class ModeBits: public BitField<OverwriteMode, 0, 2> {};
1079
  class OpBits: public BitField<Token::Value, 2, 7> {};
1080
  class PlatformSpecificBits: public BitField<bool, 9, 1> {};
1081
  class LeftTypeBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
1082
  class RightTypeBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
1083
  class ResultTypeBits: public BitField<BinaryOpIC::TypeInfo, 16, 3> {};
1084
  class HasFixedRightArgBits: public BitField<bool, 19, 1> {};
1085
  class FixedRightArgValueBits: public BitField<int, 20, 5> {};
1086

  
1087
  Major MajorKey() { return BinaryOp; }
1088
  int MinorKey() {
1089
    return OpBits::encode(op_)
1090
           | ModeBits::encode(mode_)
1091
           | PlatformSpecificBits::encode(platform_specific_bit_)
1092
           | LeftTypeBits::encode(left_type_)
1093
           | RightTypeBits::encode(right_type_)
1094
           | ResultTypeBits::encode(result_type_)
1095
           | HasFixedRightArgBits::encode(encoded_right_arg_.has_value)
1096
           | FixedRightArgValueBits::encode(encoded_right_arg_.value);
1097
  }
1130
  static Handle<Type> StateToType(State state,
1131
                                  Isolate* isolate);
1098 1132

  
1133
  static void Generate(Token::Value op,
1134
                       State left,
1135
                       int right,
1136
                       State result,
1137
                       OverwriteMode mode,
1138
                       Isolate* isolate);
1099 1139

  
1100
  // Platform-independent implementation.
1101
  void Generate(MacroAssembler* masm);
1102
  void GenerateCallRuntime(MacroAssembler* masm);
1140
  static void Generate(Token::Value op,
1141
                       State left,
1142
                       State right,
1143
                       State result,
1144
                       OverwriteMode mode,
1145
                       Isolate* isolate);
1103 1146

  
1104
  // Platform-independent signature, platform-specific implementation.
1105
  void Initialize();
1106
  void GenerateAddStrings(MacroAssembler* masm);
1107
  void GenerateBothStringStub(MacroAssembler* masm);
1108
  void GenerateGeneric(MacroAssembler* masm);
1109
  void GenerateGenericStub(MacroAssembler* masm);
1110
  void GenerateNumberStub(MacroAssembler* masm);
1111
  void GenerateInt32Stub(MacroAssembler* masm);
1112
  void GenerateLoadArguments(MacroAssembler* masm);
1113
  void GenerateOddballStub(MacroAssembler* masm);
1114
  void GenerateRegisterArgsPush(MacroAssembler* masm);
1115
  void GenerateReturn(MacroAssembler* masm);
1116
  void GenerateSmiStub(MacroAssembler* masm);
1117
  void GenerateStringStub(MacroAssembler* masm);
1118
  void GenerateTypeTransition(MacroAssembler* masm);
1119
  void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
1120
  void GenerateUninitializedStub(MacroAssembler* masm);
1121

  
1122
  // Entirely platform-specific methods are defined as static helper
1123
  // functions in the <arch>/code-stubs-<arch>.cc files.
1147
  void UpdateStatus(Handle<Object> object,
1148
                    State* state);
1124 1149

  
1125
  virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; }
1150
  bool can_encode_arg_value(int32_t value) const;
1151
  int encode_arg_value(int32_t value) const;
1152
  int32_t decode_arg_value(int value)  const;
1153
  int encode_token(Token::Value op) const;
1154
  Token::Value decode_token(int op) const;
1126 1155

  
1127
  virtual InlineCacheState GetICState() {
1128
    return BinaryOpIC::ToState(Max(left_type_, right_type_));
1156
  bool has_int_result() const {
1157
    return op_ == Token::BIT_XOR || op_ == Token::BIT_AND ||
1158
           op_ == Token::BIT_OR || op_ == Token::SAR || op_ == Token::SHL;
1129 1159
  }
1130 1160

  
1131
  virtual void FinishCode(Handle<Code> code) {
1132
    code->set_stub_info(MinorKey());
1133
  }
1161
  const char* StateToName(State state);
1162

  
1163
  void PrintBaseName(StringStream* stream);
1134 1164

  
1135
  friend class CodeGenerator;
1165
  Token::Value op_;
1166
  OverwriteMode mode_;
1167

  
1168
  Maybe<int> fixed_right_arg_;
1169
  State left_state_;
1170
  State right_state_;
1171
  State result_state_;
1136 1172
};
1137 1173

  
1138 1174

  
......
1318 1354
  virtual bool IsPregenerated(Isolate* isolate) V8_OVERRIDE;
1319 1355
  static void GenerateAheadOfTime(Isolate* isolate);
1320 1356

  
1357
 protected:
1358
  virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
1359
    ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
1360
  };
1361

  
1321 1362
 private:
1322 1363
  void GenerateCore(MacroAssembler* masm,
1323 1364
                    Label* throw_normal_exception,
......
1705 1746
      DestinationRegisterBits::encode(destination.code_) |
1706 1747
      OffsetBits::encode(offset) |
1707 1748
      IsTruncatingBits::encode(is_truncating) |
1708
      SkipFastPathBits::encode(skip_fastpath);
1749
      SkipFastPathBits::encode(skip_fastpath) |
1750
      SSEBits::encode(CpuFeatures::IsSafeForSnapshot(SSE2) ?
1751
                          CpuFeatures::IsSafeForSnapshot(SSE3) ? 2 : 1 : 0);
1709 1752
  }
1710 1753

  
1711 1754
  Register source() {
......
1734 1777

  
1735 1778
  virtual bool SometimesSetsUpAFrame() { return false; }
1736 1779

  
1780
 protected:
1781
  virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
1782
    ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
1783
  }
1784

  
1737 1785
 private:
1738 1786
  static const int kBitsPerRegisterNumber = 6;
1739 1787
  STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters);
......
1748 1796
      public BitField<int, 2 * kBitsPerRegisterNumber + 1, 3> {};  // NOLINT
1749 1797
  class SkipFastPathBits:
1750 1798
      public BitField<int, 2 * kBitsPerRegisterNumber + 4, 1> {};  // NOLINT
1799
  class SSEBits:
1800
      public BitField<int, 2 * kBitsPerRegisterNumber + 5, 2> {};  // NOLINT
1751 1801

  
1752 1802
  Major MajorKey() { return DoubleToI; }
1753 1803
  int MinorKey() { return bit_field_; }

Also available in: Unified diff