| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 GenericBinaryOpStub(Token::Value op, | 76 GenericBinaryOpStub(Token::Value op, |
| 77 OverwriteMode mode, | 77 OverwriteMode mode, |
| 78 GenericBinaryFlags flags, | 78 GenericBinaryFlags flags, |
| 79 TypeInfo operands_type) | 79 TypeInfo operands_type) |
| 80 : op_(op), | 80 : op_(op), |
| 81 mode_(mode), | 81 mode_(mode), |
| 82 flags_(flags), | 82 flags_(flags), |
| 83 args_in_registers_(false), | 83 args_in_registers_(false), |
| 84 args_reversed_(false), | 84 args_reversed_(false), |
| 85 static_operands_type_(operands_type), | 85 static_operands_type_(operands_type), |
| 86 runtime_operands_type_(BinaryOpIC::DEFAULT), | 86 runtime_operands_type_(BinaryOpIC::UNINIT_OR_SMI), |
| 87 name_(NULL) { | 87 name_(NULL) { |
| 88 if (static_operands_type_.IsSmi()) { | 88 if (static_operands_type_.IsSmi()) { |
| 89 mode_ = NO_OVERWRITE; | 89 mode_ = NO_OVERWRITE; |
| 90 } | 90 } |
| 91 use_sse3_ = Isolate::Current()->cpu_features()->IsSupported(SSE3); | 91 use_sse3_ = Isolate::Current()->cpu_features()->IsSupported(SSE3); |
| 92 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); | 92 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
| 93 } | 93 } |
| 94 | 94 |
| 95 GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo runtime_operands_type) | 95 GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo runtime_operands_type) |
| 96 : op_(OpBits::decode(key)), | 96 : op_(OpBits::decode(key)), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 110 // stack together with the actual call. | 110 // stack together with the actual call. |
| 111 void GenerateCall(MacroAssembler* masm, Register left, Register right); | 111 void GenerateCall(MacroAssembler* masm, Register left, Register right); |
| 112 void GenerateCall(MacroAssembler* masm, Register left, Smi* right); | 112 void GenerateCall(MacroAssembler* masm, Register left, Smi* right); |
| 113 void GenerateCall(MacroAssembler* masm, Smi* left, Register right); | 113 void GenerateCall(MacroAssembler* masm, Smi* left, Register right); |
| 114 | 114 |
| 115 bool ArgsInRegistersSupported() { | 115 bool ArgsInRegistersSupported() { |
| 116 return op_ == Token::ADD || op_ == Token::SUB | 116 return op_ == Token::ADD || op_ == Token::SUB |
| 117 || op_ == Token::MUL || op_ == Token::DIV; | 117 || op_ == Token::MUL || op_ == Token::DIV; |
| 118 } | 118 } |
| 119 | 119 |
| 120 void SetArgsInRegisters() { |
| 121 ASSERT(ArgsInRegistersSupported()); |
| 122 args_in_registers_ = true; |
| 123 } |
| 124 |
| 120 private: | 125 private: |
| 121 Token::Value op_; | 126 Token::Value op_; |
| 122 OverwriteMode mode_; | 127 OverwriteMode mode_; |
| 123 GenericBinaryFlags flags_; | 128 GenericBinaryFlags flags_; |
| 124 bool args_in_registers_; // Arguments passed in registers not on the stack. | 129 bool args_in_registers_; // Arguments passed in registers not on the stack. |
| 125 bool args_reversed_; // Left and right argument are swapped. | 130 bool args_reversed_; // Left and right argument are swapped. |
| 126 bool use_sse3_; | 131 bool use_sse3_; |
| 127 | 132 |
| 128 // Number type information of operands, determined by code generator. | 133 // Number type information of operands, determined by code generator. |
| 129 TypeInfo static_operands_type_; | 134 TypeInfo static_operands_type_; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 150 #endif | 155 #endif |
| 151 | 156 |
| 152 // Minor key encoding in 18 bits RRNNNFRASOOOOOOOMM. | 157 // Minor key encoding in 18 bits RRNNNFRASOOOOOOOMM. |
| 153 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; | 158 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
| 154 class OpBits: public BitField<Token::Value, 2, 7> {}; | 159 class OpBits: public BitField<Token::Value, 2, 7> {}; |
| 155 class SSE3Bits: public BitField<bool, 9, 1> {}; | 160 class SSE3Bits: public BitField<bool, 9, 1> {}; |
| 156 class ArgsInRegistersBits: public BitField<bool, 10, 1> {}; | 161 class ArgsInRegistersBits: public BitField<bool, 10, 1> {}; |
| 157 class ArgsReversedBits: public BitField<bool, 11, 1> {}; | 162 class ArgsReversedBits: public BitField<bool, 11, 1> {}; |
| 158 class FlagBits: public BitField<GenericBinaryFlags, 12, 1> {}; | 163 class FlagBits: public BitField<GenericBinaryFlags, 12, 1> {}; |
| 159 class StaticTypeInfoBits: public BitField<int, 13, 3> {}; | 164 class StaticTypeInfoBits: public BitField<int, 13, 3> {}; |
| 160 class RuntimeTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 16, 2> {}; | 165 class RuntimeTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 16, 3> {}; |
| 161 | 166 |
| 162 Major MajorKey() { return GenericBinaryOp; } | 167 Major MajorKey() { return GenericBinaryOp; } |
| 163 int MinorKey() { | 168 int MinorKey() { |
| 164 // Encode the parameters in a unique 18 bit value. | 169 // Encode the parameters in a unique 18 bit value. |
| 165 return OpBits::encode(op_) | 170 return OpBits::encode(op_) |
| 166 | ModeBits::encode(mode_) | 171 | ModeBits::encode(mode_) |
| 167 | FlagBits::encode(flags_) | 172 | FlagBits::encode(flags_) |
| 168 | SSE3Bits::encode(use_sse3_) | 173 | SSE3Bits::encode(use_sse3_) |
| 169 | ArgsInRegistersBits::encode(args_in_registers_) | 174 | ArgsInRegistersBits::encode(args_in_registers_) |
| 170 | ArgsReversedBits::encode(args_reversed_) | 175 | ArgsReversedBits::encode(args_reversed_) |
| 171 | StaticTypeInfoBits::encode( | 176 | StaticTypeInfoBits::encode( |
| 172 static_operands_type_.ThreeBitRepresentation()) | 177 static_operands_type_.ThreeBitRepresentation()) |
| 173 | RuntimeTypeInfoBits::encode(runtime_operands_type_); | 178 | RuntimeTypeInfoBits::encode(runtime_operands_type_); |
| 174 } | 179 } |
| 175 | 180 |
| 176 void Generate(MacroAssembler* masm); | 181 void Generate(MacroAssembler* masm); |
| 177 void GenerateSmiCode(MacroAssembler* masm, Label* slow); | 182 void GenerateSmiCode(MacroAssembler* masm, Label* slow); |
| 178 void GenerateLoadArguments(MacroAssembler* masm); | 183 void GenerateLoadArguments(MacroAssembler* masm); |
| 179 void GenerateReturn(MacroAssembler* masm); | 184 void GenerateReturn(MacroAssembler* masm); |
| 180 void GenerateHeapResultAllocation(MacroAssembler* masm, Label* alloc_failure); | 185 void GenerateHeapResultAllocation(MacroAssembler* masm, Label* alloc_failure); |
| 181 void GenerateRegisterArgsPush(MacroAssembler* masm); | 186 void GenerateRegisterArgsPush(MacroAssembler* masm); |
| 182 void GenerateTypeTransition(MacroAssembler* masm); | 187 void GenerateTypeTransition(MacroAssembler* masm); |
| 183 | 188 |
| 184 bool IsOperationCommutative() { | 189 bool IsOperationCommutative() { |
| 185 return (op_ == Token::ADD) || (op_ == Token::MUL); | 190 return (op_ == Token::ADD) || (op_ == Token::MUL); |
| 186 } | 191 } |
| 187 | 192 |
| 188 void SetArgsInRegisters() { args_in_registers_ = true; } | |
| 189 void SetArgsReversed() { args_reversed_ = true; } | 193 void SetArgsReversed() { args_reversed_ = true; } |
| 190 bool HasSmiCodeInStub() { return (flags_ & NO_SMI_CODE_IN_STUB) == 0; } | 194 bool HasSmiCodeInStub() { return (flags_ & NO_SMI_CODE_IN_STUB) == 0; } |
| 191 bool HasArgsInRegisters() { return args_in_registers_; } | 195 bool HasArgsInRegisters() { return args_in_registers_; } |
| 192 bool HasArgsReversed() { return args_reversed_; } | 196 bool HasArgsReversed() { return args_reversed_; } |
| 193 | 197 |
| 194 bool ShouldGenerateSmiCode() { | 198 bool ShouldGenerateSmiCode() { |
| 195 return HasSmiCodeInStub() && | 199 return HasSmiCodeInStub() && |
| 196 runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS && | 200 runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS && |
| 197 runtime_operands_type_ != BinaryOpIC::STRINGS; | 201 runtime_operands_type_ != BinaryOpIC::STRINGS; |
| 198 } | 202 } |
| 199 | 203 |
| 200 bool ShouldGenerateFPCode() { | 204 bool ShouldGenerateFPCode() { |
| 201 return runtime_operands_type_ != BinaryOpIC::STRINGS; | 205 return runtime_operands_type_ != BinaryOpIC::STRINGS; |
| 202 } | 206 } |
| 203 | 207 |
| 204 virtual int GetCodeKind() { return Code::BINARY_OP_IC; } | 208 virtual int GetCodeKind() { return Code::BINARY_OP_IC; } |
| 205 | 209 |
| 206 virtual InlineCacheState GetICState() { | 210 virtual InlineCacheState GetICState() { |
| 207 return BinaryOpIC::ToState(runtime_operands_type_); | 211 return BinaryOpIC::ToState(runtime_operands_type_); |
| 208 } | 212 } |
| 209 | 213 |
| 214 virtual void FinishCode(Code* code) { |
| 215 code->set_binary_op_type(runtime_operands_type_); |
| 216 } |
| 217 |
| 210 friend class CodeGenerator; | 218 friend class CodeGenerator; |
| 211 }; | 219 }; |
| 212 | 220 |
| 221 |
| 222 class TypeRecordingBinaryOpStub: public CodeStub { |
| 223 public: |
| 224 TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode) |
| 225 : op_(op), |
| 226 mode_(mode), |
| 227 operands_type_(TRBinaryOpIC::UNINITIALIZED), |
| 228 result_type_(TRBinaryOpIC::UNINITIALIZED), |
| 229 name_(NULL) { |
| 230 use_sse3_ = Isolate::Current()->cpu_features()->IsSupported(SSE3); |
| 231 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
| 232 } |
| 233 |
| 234 TypeRecordingBinaryOpStub(int key, |
| 235 TRBinaryOpIC::TypeInfo operands_type, |
| 236 TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED) |
| 237 : op_(OpBits::decode(key)), |
| 238 mode_(ModeBits::decode(key)), |
| 239 use_sse3_(SSE3Bits::decode(key)), |
| 240 operands_type_(operands_type), |
| 241 result_type_(result_type), |
| 242 name_(NULL) { |
| 243 } |
| 244 |
| 245 // Generate code to call the stub with the supplied arguments. This will add |
| 246 // code at the call site to prepare arguments either in registers or on the |
| 247 // stack together with the actual call. |
| 248 void GenerateCall(MacroAssembler* masm, Register left, Register right); |
| 249 void GenerateCall(MacroAssembler* masm, Register left, Smi* right); |
| 250 void GenerateCall(MacroAssembler* masm, Smi* left, Register right); |
| 251 |
| 252 private: |
| 253 enum SmiCodeGenerateHeapNumberResults { |
| 254 ALLOW_HEAPNUMBER_RESULTS, |
| 255 NO_HEAPNUMBER_RESULTS |
| 256 }; |
| 257 |
| 258 Token::Value op_; |
| 259 OverwriteMode mode_; |
| 260 bool use_sse3_; |
| 261 |
| 262 // Operand type information determined at runtime. |
| 263 TRBinaryOpIC::TypeInfo operands_type_; |
| 264 TRBinaryOpIC::TypeInfo result_type_; |
| 265 |
| 266 char* name_; |
| 267 |
| 268 const char* GetName(); |
| 269 |
| 270 #ifdef DEBUG |
| 271 void Print() { |
| 272 PrintF("TypeRecordingBinaryOpStub %d (op %s), " |
| 273 "(mode %d, runtime_type_info %s)\n", |
| 274 MinorKey(), |
| 275 Token::String(op_), |
| 276 static_cast<int>(mode_), |
| 277 TRBinaryOpIC::GetName(operands_type_)); |
| 278 } |
| 279 #endif |
| 280 |
| 281 // Minor key encoding in 16 bits RRRTTTSOOOOOOOMM. |
| 282 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
| 283 class OpBits: public BitField<Token::Value, 2, 7> {}; |
| 284 class SSE3Bits: public BitField<bool, 9, 1> {}; |
| 285 class OperandTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 10, 3> {}; |
| 286 class ResultTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 13, 3> {}; |
| 287 |
| 288 Major MajorKey() { return TypeRecordingBinaryOp; } |
| 289 int MinorKey() { |
| 290 return OpBits::encode(op_) |
| 291 | ModeBits::encode(mode_) |
| 292 | SSE3Bits::encode(use_sse3_) |
| 293 | OperandTypeInfoBits::encode(operands_type_) |
| 294 | ResultTypeInfoBits::encode(result_type_); |
| 295 } |
| 296 |
| 297 void Generate(MacroAssembler* masm); |
| 298 void GenerateGeneric(MacroAssembler* masm); |
| 299 void GenerateSmiCode(MacroAssembler* masm, |
| 300 Label* slow, |
| 301 SmiCodeGenerateHeapNumberResults heapnumber_results); |
| 302 void GenerateLoadArguments(MacroAssembler* masm); |
| 303 void GenerateReturn(MacroAssembler* masm); |
| 304 void GenerateUninitializedStub(MacroAssembler* masm); |
| 305 void GenerateSmiStub(MacroAssembler* masm); |
| 306 void GenerateInt32Stub(MacroAssembler* masm); |
| 307 void GenerateHeapNumberStub(MacroAssembler* masm); |
| 308 void GenerateStringStub(MacroAssembler* masm); |
| 309 void GenerateGenericStub(MacroAssembler* masm); |
| 310 |
| 311 void GenerateHeapResultAllocation(MacroAssembler* masm, Label* alloc_failure); |
| 312 void GenerateRegisterArgsPush(MacroAssembler* masm); |
| 313 void GenerateTypeTransition(MacroAssembler* masm); |
| 314 void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm); |
| 315 |
| 316 bool IsOperationCommutative() { |
| 317 return (op_ == Token::ADD) || (op_ == Token::MUL); |
| 318 } |
| 319 |
| 320 virtual int GetCodeKind() { return Code::TYPE_RECORDING_BINARY_OP_IC; } |
| 321 |
| 322 virtual InlineCacheState GetICState() { |
| 323 return TRBinaryOpIC::ToState(operands_type_); |
| 324 } |
| 325 |
| 326 virtual void FinishCode(Code* code) { |
| 327 code->set_type_recording_binary_op_type(operands_type_); |
| 328 code->set_type_recording_binary_op_result_type(result_type_); |
| 329 } |
| 330 |
| 331 friend class CodeGenerator; |
| 332 }; |
| 333 |
| 213 | 334 |
| 214 class StringHelper : public AllStatic { | 335 class StringHelper : public AllStatic { |
| 215 public: | 336 public: |
| 216 // Generate code for copying characters using a simple loop. This should only | 337 // Generate code for copying characters using a simple loop. This should only |
| 217 // be used in places where the number of characters is small and the | 338 // be used in places where the number of characters is small and the |
| 218 // additional setup and checking in GenerateCopyCharactersREP adds too much | 339 // additional setup and checking in GenerateCopyCharactersREP adds too much |
| 219 // overhead. Copying of overlapping regions is not supported. | 340 // overhead. Copying of overlapping regions is not supported. |
| 220 static void GenerateCopyCharacters(MacroAssembler* masm, | 341 static void GenerateCopyCharacters(MacroAssembler* masm, |
| 221 Register dest, | 342 Register dest, |
| 222 Register src, | 343 Register src, |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 void Print() { | 488 void Print() { |
| 368 PrintF("NumberToStringStub\n"); | 489 PrintF("NumberToStringStub\n"); |
| 369 } | 490 } |
| 370 #endif | 491 #endif |
| 371 }; | 492 }; |
| 372 | 493 |
| 373 | 494 |
| 374 } } // namespace v8::internal | 495 } } // namespace v8::internal |
| 375 | 496 |
| 376 #endif // V8_IA32_CODE_STUBS_IA32_H_ | 497 #endif // V8_IA32_CODE_STUBS_IA32_H_ |
| OLD | NEW |