| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 // GC. This means that we must be statically sure that no GC can occur while | 155 // GC. This means that we must be statically sure that no GC can occur while |
| 156 // they are running. If that is the case they should override this to return | 156 // they are running. If that is the case they should override this to return |
| 157 // true, which will cause an assertion if we try to call something that can | 157 // true, which will cause an assertion if we try to call something that can |
| 158 // GC or if we try to put a stack frame on top of the junk, which would not | 158 // GC or if we try to put a stack frame on top of the junk, which would not |
| 159 // result in a traversable stack. | 159 // result in a traversable stack. |
| 160 virtual bool SometimesSetsUpAFrame() { return true; } | 160 virtual bool SometimesSetsUpAFrame() { return true; } |
| 161 | 161 |
| 162 // Lookup the code in the (possibly custom) cache. | 162 // Lookup the code in the (possibly custom) cache. |
| 163 bool FindCodeInCache(Code** code_out, Isolate* isolate); | 163 bool FindCodeInCache(Code** code_out, Isolate* isolate); |
| 164 | 164 |
| 165 // Returns information for computing the number key. | |
| 166 virtual Major MajorKey() = 0; | |
| 167 virtual int MinorKey() = 0; | |
| 168 | |
| 169 protected: | 165 protected: |
| 170 static bool CanUseFPRegisters(); | 166 static bool CanUseFPRegisters(); |
| 171 | 167 |
| 168 private: |
| 169 // Nonvirtual wrapper around the stub-specific Generate function. Call |
| 170 // this function to set up the macro assembler and generate the code. |
| 171 void GenerateCode(MacroAssembler* masm); |
| 172 |
| 172 // Generates the assembler code for the stub. | 173 // Generates the assembler code for the stub. |
| 173 virtual Handle<Code> GenerateCode() = 0; | 174 virtual void Generate(MacroAssembler* masm) = 0; |
| 174 | 175 |
| 175 // BinaryOpStub needs to override this. | |
| 176 virtual InlineCacheState GetICState() { | |
| 177 return UNINITIALIZED; | |
| 178 } | |
| 179 | |
| 180 // Returns whether the code generated for this stub needs to be allocated as | |
| 181 // a fixed (non-moveable) code object. | |
| 182 virtual bool NeedsImmovableCode() { return false; } | |
| 183 | |
| 184 private: | |
| 185 // Perform bookkeeping required after code generation when stub code is | 176 // Perform bookkeeping required after code generation when stub code is |
| 186 // initially generated. | 177 // initially generated. |
| 187 void RecordCodeGeneration(Code* code, Isolate* isolate); | 178 void RecordCodeGeneration(Code* code, MacroAssembler* masm); |
| 188 | 179 |
| 189 // Finish the code object after it has been generated. | 180 // Finish the code object after it has been generated. |
| 190 virtual void FinishCode(Handle<Code> code) { } | 181 virtual void FinishCode(Handle<Code> code) { } |
| 191 | 182 |
| 192 // Activate newly generated stub. Is called after | 183 // Activate newly generated stub. Is called after |
| 193 // registering stub in the stub cache. | 184 // registering stub in the stub cache. |
| 194 virtual void Activate(Code* code) { } | 185 virtual void Activate(Code* code) { } |
| 195 | 186 |
| 187 // Returns information for computing the number key. |
| 188 virtual Major MajorKey() = 0; |
| 189 virtual int MinorKey() = 0; |
| 190 |
| 196 // BinaryOpStub needs to override this. | 191 // BinaryOpStub needs to override this. |
| 197 virtual int GetCodeKind(); | 192 virtual int GetCodeKind(); |
| 198 | 193 |
| 194 // BinaryOpStub needs to override this. |
| 195 virtual InlineCacheState GetICState() { |
| 196 return UNINITIALIZED; |
| 197 } |
| 198 |
| 199 // Add the code to a specialized cache, specific to an individual | 199 // Add the code to a specialized cache, specific to an individual |
| 200 // stub type. Please note, this method must add the code object to a | 200 // stub type. Please note, this method must add the code object to a |
| 201 // roots object, otherwise we will remove the code during GC. | 201 // roots object, otherwise we will remove the code during GC. |
| 202 virtual void AddToSpecialCache(Handle<Code> new_object) { } | 202 virtual void AddToSpecialCache(Handle<Code> new_object) { } |
| 203 | 203 |
| 204 // Find code in a specialized cache, work is delegated to the specific stub. | 204 // Find code in a specialized cache, work is delegated to the specific stub. |
| 205 virtual bool FindCodeInSpecialCache(Code** code_out, Isolate* isolate) { | 205 virtual bool FindCodeInSpecialCache(Code** code_out, Isolate* isolate) { |
| 206 return false; | 206 return false; |
| 207 } | 207 } |
| 208 | 208 |
| 209 // If a stub uses a special cache override this. | 209 // If a stub uses a special cache override this. |
| 210 virtual bool UseSpecialCache() { return false; } | 210 virtual bool UseSpecialCache() { return false; } |
| 211 | 211 |
| 212 // Returns a name for logging/debugging purposes. | 212 // Returns a name for logging/debugging purposes. |
| 213 SmartArrayPointer<const char> GetName(); | 213 SmartArrayPointer<const char> GetName(); |
| 214 virtual void PrintName(StringStream* stream); | 214 virtual void PrintName(StringStream* stream); |
| 215 | 215 |
| 216 // Returns whether the code generated for this stub needs to be allocated as |
| 217 // a fixed (non-moveable) code object. |
| 218 virtual bool NeedsImmovableCode() { return false; } |
| 219 |
| 216 // Computes the key based on major and minor. | 220 // Computes the key based on major and minor. |
| 217 uint32_t GetKey() { | 221 uint32_t GetKey() { |
| 218 ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); | 222 ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS); |
| 219 return MinorKeyBits::encode(MinorKey()) | | 223 return MinorKeyBits::encode(MinorKey()) | |
| 220 MajorKeyBits::encode(MajorKey()); | 224 MajorKeyBits::encode(MajorKey()); |
| 221 } | 225 } |
| 222 | 226 |
| 223 class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {}; | 227 class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {}; |
| 224 class MinorKeyBits: public BitField<uint32_t, | 228 class MinorKeyBits: public BitField<uint32_t, |
| 225 kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT | 229 kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT |
| 226 | 230 |
| 227 friend class BreakPointIterator; | 231 friend class BreakPointIterator; |
| 228 }; | 232 }; |
| 229 | 233 |
| 230 | 234 |
| 231 class PlatformCodeStub : public CodeStub { | |
| 232 public: | |
| 233 // Retrieve the code for the stub. Generate the code if needed. | |
| 234 virtual Handle<Code> GenerateCode(); | |
| 235 | |
| 236 virtual int GetCodeKind() { return Code::STUB; } | |
| 237 | |
| 238 protected: | |
| 239 // Generates the assembler code for the stub. | |
| 240 virtual void Generate(MacroAssembler* masm) = 0; | |
| 241 }; | |
| 242 | |
| 243 | |
| 244 struct CodeStubInterfaceDescriptor { | |
| 245 CodeStubInterfaceDescriptor() | |
| 246 : register_param_count_(-1), | |
| 247 register_params_(NULL) { } | |
| 248 int register_param_count_; | |
| 249 Register* register_params_; | |
| 250 Handle<Code> deoptimization_handler_; | |
| 251 }; | |
| 252 | |
| 253 | |
| 254 class HGraph; | |
| 255 struct Register; | |
| 256 class HydrogenCodeStub : public CodeStub { | |
| 257 public: | |
| 258 // Retrieve the code for the stub. Generate the code if needed. | |
| 259 virtual Handle<Code> GenerateCode() = 0; | |
| 260 | |
| 261 virtual int GetCodeKind() { return Code::COMPILED_STUB; } | |
| 262 | |
| 263 CodeStubInterfaceDescriptor* GetInterfaceDescriptor(Isolate* isolate) { | |
| 264 return isolate->code_stub_interface_descriptor(MajorKey()); | |
| 265 } | |
| 266 | |
| 267 virtual void InitializeInterfaceDescriptor( | |
| 268 Isolate* isolate, | |
| 269 CodeStubInterfaceDescriptor* descriptor) = 0; | |
| 270 | |
| 271 protected: | |
| 272 Handle<Code> CodeFromGraph(HGraph* graph); | |
| 273 }; | |
| 274 | |
| 275 | |
| 276 // Helper interface to prepare to/restore after making runtime calls. | 235 // Helper interface to prepare to/restore after making runtime calls. |
| 277 class RuntimeCallHelper { | 236 class RuntimeCallHelper { |
| 278 public: | 237 public: |
| 279 virtual ~RuntimeCallHelper() {} | 238 virtual ~RuntimeCallHelper() {} |
| 280 | 239 |
| 281 virtual void BeforeCall(MacroAssembler* masm) const = 0; | 240 virtual void BeforeCall(MacroAssembler* masm) const = 0; |
| 282 | 241 |
| 283 virtual void AfterCall(MacroAssembler* masm) const = 0; | 242 virtual void AfterCall(MacroAssembler* masm) const = 0; |
| 284 | 243 |
| 285 protected: | 244 protected: |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 class NopRuntimeCallHelper : public RuntimeCallHelper { | 282 class NopRuntimeCallHelper : public RuntimeCallHelper { |
| 324 public: | 283 public: |
| 325 NopRuntimeCallHelper() {} | 284 NopRuntimeCallHelper() {} |
| 326 | 285 |
| 327 virtual void BeforeCall(MacroAssembler* masm) const {} | 286 virtual void BeforeCall(MacroAssembler* masm) const {} |
| 328 | 287 |
| 329 virtual void AfterCall(MacroAssembler* masm) const {} | 288 virtual void AfterCall(MacroAssembler* masm) const {} |
| 330 }; | 289 }; |
| 331 | 290 |
| 332 | 291 |
| 333 class StackCheckStub : public PlatformCodeStub { | 292 class StackCheckStub : public CodeStub { |
| 334 public: | 293 public: |
| 335 StackCheckStub() { } | 294 StackCheckStub() { } |
| 336 | 295 |
| 337 void Generate(MacroAssembler* masm); | 296 void Generate(MacroAssembler* masm); |
| 338 | 297 |
| 339 private: | 298 private: |
| 340 Major MajorKey() { return StackCheck; } | 299 Major MajorKey() { return StackCheck; } |
| 341 int MinorKey() { return 0; } | 300 int MinorKey() { return 0; } |
| 342 }; | 301 }; |
| 343 | 302 |
| 344 | 303 |
| 345 class InterruptStub : public PlatformCodeStub { | 304 class InterruptStub : public CodeStub { |
| 346 public: | 305 public: |
| 347 InterruptStub() { } | 306 InterruptStub() { } |
| 348 | 307 |
| 349 void Generate(MacroAssembler* masm); | 308 void Generate(MacroAssembler* masm); |
| 350 | 309 |
| 351 private: | 310 private: |
| 352 Major MajorKey() { return Interrupt; } | 311 Major MajorKey() { return Interrupt; } |
| 353 int MinorKey() { return 0; } | 312 int MinorKey() { return 0; } |
| 354 }; | 313 }; |
| 355 | 314 |
| 356 | 315 |
| 357 class ToNumberStub: public PlatformCodeStub { | 316 class ToNumberStub: public CodeStub { |
| 358 public: | 317 public: |
| 359 ToNumberStub() { } | 318 ToNumberStub() { } |
| 360 | 319 |
| 361 void Generate(MacroAssembler* masm); | 320 void Generate(MacroAssembler* masm); |
| 362 | 321 |
| 363 private: | 322 private: |
| 364 Major MajorKey() { return ToNumber; } | 323 Major MajorKey() { return ToNumber; } |
| 365 int MinorKey() { return 0; } | 324 int MinorKey() { return 0; } |
| 366 }; | 325 }; |
| 367 | 326 |
| 368 | 327 |
| 369 class FastNewClosureStub : public PlatformCodeStub { | 328 class FastNewClosureStub : public CodeStub { |
| 370 public: | 329 public: |
| 371 explicit FastNewClosureStub(LanguageMode language_mode) | 330 explicit FastNewClosureStub(LanguageMode language_mode) |
| 372 : language_mode_(language_mode) { } | 331 : language_mode_(language_mode) { } |
| 373 | 332 |
| 374 void Generate(MacroAssembler* masm); | 333 void Generate(MacroAssembler* masm); |
| 375 | 334 |
| 376 private: | 335 private: |
| 377 Major MajorKey() { return FastNewClosure; } | 336 Major MajorKey() { return FastNewClosure; } |
| 378 int MinorKey() { return language_mode_ == CLASSIC_MODE | 337 int MinorKey() { return language_mode_ == CLASSIC_MODE |
| 379 ? kNonStrictMode : kStrictMode; } | 338 ? kNonStrictMode : kStrictMode; } |
| 380 | 339 |
| 381 LanguageMode language_mode_; | 340 LanguageMode language_mode_; |
| 382 }; | 341 }; |
| 383 | 342 |
| 384 | 343 |
| 385 class FastNewContextStub : public PlatformCodeStub { | 344 class FastNewContextStub : public CodeStub { |
| 386 public: | 345 public: |
| 387 static const int kMaximumSlots = 64; | 346 static const int kMaximumSlots = 64; |
| 388 | 347 |
| 389 explicit FastNewContextStub(int slots) : slots_(slots) { | 348 explicit FastNewContextStub(int slots) : slots_(slots) { |
| 390 ASSERT(slots_ > 0 && slots_ <= kMaximumSlots); | 349 ASSERT(slots_ > 0 && slots_ <= kMaximumSlots); |
| 391 } | 350 } |
| 392 | 351 |
| 393 void Generate(MacroAssembler* masm); | 352 void Generate(MacroAssembler* masm); |
| 394 | 353 |
| 395 private: | 354 private: |
| 396 int slots_; | 355 int slots_; |
| 397 | 356 |
| 398 Major MajorKey() { return FastNewContext; } | 357 Major MajorKey() { return FastNewContext; } |
| 399 int MinorKey() { return slots_; } | 358 int MinorKey() { return slots_; } |
| 400 }; | 359 }; |
| 401 | 360 |
| 402 | 361 |
| 403 class FastNewBlockContextStub : public PlatformCodeStub { | 362 class FastNewBlockContextStub : public CodeStub { |
| 404 public: | 363 public: |
| 405 static const int kMaximumSlots = 64; | 364 static const int kMaximumSlots = 64; |
| 406 | 365 |
| 407 explicit FastNewBlockContextStub(int slots) : slots_(slots) { | 366 explicit FastNewBlockContextStub(int slots) : slots_(slots) { |
| 408 ASSERT(slots_ > 0 && slots_ <= kMaximumSlots); | 367 ASSERT(slots_ > 0 && slots_ <= kMaximumSlots); |
| 409 } | 368 } |
| 410 | 369 |
| 411 void Generate(MacroAssembler* masm); | 370 void Generate(MacroAssembler* masm); |
| 412 | 371 |
| 413 private: | 372 private: |
| 414 int slots_; | 373 int slots_; |
| 415 | 374 |
| 416 Major MajorKey() { return FastNewBlockContext; } | 375 Major MajorKey() { return FastNewBlockContext; } |
| 417 int MinorKey() { return slots_; } | 376 int MinorKey() { return slots_; } |
| 418 }; | 377 }; |
| 419 | 378 |
| 420 | 379 |
| 421 class FastCloneShallowArrayStub : public PlatformCodeStub { | 380 class FastCloneShallowArrayStub : public CodeStub { |
| 422 public: | 381 public: |
| 423 // Maximum length of copied elements array. | 382 // Maximum length of copied elements array. |
| 424 static const int kMaximumClonedLength = 8; | 383 static const int kMaximumClonedLength = 8; |
| 425 | 384 |
| 426 enum Mode { | 385 enum Mode { |
| 427 CLONE_ELEMENTS, | 386 CLONE_ELEMENTS, |
| 428 CLONE_DOUBLE_ELEMENTS, | 387 CLONE_DOUBLE_ELEMENTS, |
| 429 COPY_ON_WRITE_ELEMENTS, | 388 COPY_ON_WRITE_ELEMENTS, |
| 430 CLONE_ANY_ELEMENTS | 389 CLONE_ANY_ELEMENTS |
| 431 }; | 390 }; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 444 int length_; | 403 int length_; |
| 445 | 404 |
| 446 Major MajorKey() { return FastCloneShallowArray; } | 405 Major MajorKey() { return FastCloneShallowArray; } |
| 447 int MinorKey() { | 406 int MinorKey() { |
| 448 ASSERT(mode_ == 0 || mode_ == 1 || mode_ == 2 || mode_ == 3); | 407 ASSERT(mode_ == 0 || mode_ == 1 || mode_ == 2 || mode_ == 3); |
| 449 return length_ * 4 + mode_; | 408 return length_ * 4 + mode_; |
| 450 } | 409 } |
| 451 }; | 410 }; |
| 452 | 411 |
| 453 | 412 |
| 454 class FastCloneShallowObjectStub : public PlatformCodeStub { | 413 class FastCloneShallowObjectStub : public CodeStub { |
| 455 public: | 414 public: |
| 456 // Maximum number of properties in copied object. | 415 // Maximum number of properties in copied object. |
| 457 static const int kMaximumClonedProperties = 6; | 416 static const int kMaximumClonedProperties = 6; |
| 458 | 417 |
| 459 explicit FastCloneShallowObjectStub(int length) : length_(length) { | 418 explicit FastCloneShallowObjectStub(int length) : length_(length) { |
| 460 ASSERT_GE(length_, 0); | 419 ASSERT_GE(length_, 0); |
| 461 ASSERT_LE(length_, kMaximumClonedProperties); | 420 ASSERT_LE(length_, kMaximumClonedProperties); |
| 462 } | 421 } |
| 463 | 422 |
| 464 void Generate(MacroAssembler* masm); | 423 void Generate(MacroAssembler* masm); |
| 465 | 424 |
| 466 private: | 425 private: |
| 467 int length_; | 426 int length_; |
| 468 | 427 |
| 469 Major MajorKey() { return FastCloneShallowObject; } | 428 Major MajorKey() { return FastCloneShallowObject; } |
| 470 int MinorKey() { return length_; } | 429 int MinorKey() { return length_; } |
| 471 }; | 430 }; |
| 472 | 431 |
| 473 | 432 |
| 474 class InstanceofStub: public PlatformCodeStub { | 433 class InstanceofStub: public CodeStub { |
| 475 public: | 434 public: |
| 476 enum Flags { | 435 enum Flags { |
| 477 kNoFlags = 0, | 436 kNoFlags = 0, |
| 478 kArgsInRegisters = 1 << 0, | 437 kArgsInRegisters = 1 << 0, |
| 479 kCallSiteInlineCheck = 1 << 1, | 438 kCallSiteInlineCheck = 1 << 1, |
| 480 kReturnTrueFalseObject = 1 << 2 | 439 kReturnTrueFalseObject = 1 << 2 |
| 481 }; | 440 }; |
| 482 | 441 |
| 483 explicit InstanceofStub(Flags flags) : flags_(flags) { } | 442 explicit InstanceofStub(Flags flags) : flags_(flags) { } |
| 484 | 443 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 502 bool ReturnTrueFalseObject() const { | 461 bool ReturnTrueFalseObject() const { |
| 503 return (flags_ & kReturnTrueFalseObject) != 0; | 462 return (flags_ & kReturnTrueFalseObject) != 0; |
| 504 } | 463 } |
| 505 | 464 |
| 506 virtual void PrintName(StringStream* stream); | 465 virtual void PrintName(StringStream* stream); |
| 507 | 466 |
| 508 Flags flags_; | 467 Flags flags_; |
| 509 }; | 468 }; |
| 510 | 469 |
| 511 | 470 |
| 512 class MathPowStub: public PlatformCodeStub { | 471 class MathPowStub: public CodeStub { |
| 513 public: | 472 public: |
| 514 enum ExponentType { INTEGER, DOUBLE, TAGGED, ON_STACK}; | 473 enum ExponentType { INTEGER, DOUBLE, TAGGED, ON_STACK}; |
| 515 | 474 |
| 516 explicit MathPowStub(ExponentType exponent_type) | 475 explicit MathPowStub(ExponentType exponent_type) |
| 517 : exponent_type_(exponent_type) { } | 476 : exponent_type_(exponent_type) { } |
| 518 virtual void Generate(MacroAssembler* masm); | 477 virtual void Generate(MacroAssembler* masm); |
| 519 | 478 |
| 520 private: | 479 private: |
| 521 virtual CodeStub::Major MajorKey() { return MathPow; } | 480 virtual CodeStub::Major MajorKey() { return MathPow; } |
| 522 virtual int MinorKey() { return exponent_type_; } | 481 virtual int MinorKey() { return exponent_type_; } |
| 523 | 482 |
| 524 ExponentType exponent_type_; | 483 ExponentType exponent_type_; |
| 525 }; | 484 }; |
| 526 | 485 |
| 527 | 486 |
| 528 class BinaryOpStub: public PlatformCodeStub { | 487 class BinaryOpStub: public CodeStub { |
| 529 public: | 488 public: |
| 530 BinaryOpStub(Token::Value op, OverwriteMode mode) | 489 BinaryOpStub(Token::Value op, OverwriteMode mode) |
| 531 : op_(op), | 490 : op_(op), |
| 532 mode_(mode), | 491 mode_(mode), |
| 533 platform_specific_bit_(false), | 492 platform_specific_bit_(false), |
| 534 left_type_(BinaryOpIC::UNINITIALIZED), | 493 left_type_(BinaryOpIC::UNINITIALIZED), |
| 535 right_type_(BinaryOpIC::UNINITIALIZED), | 494 right_type_(BinaryOpIC::UNINITIALIZED), |
| 536 result_type_(BinaryOpIC::UNINITIALIZED) { | 495 result_type_(BinaryOpIC::UNINITIALIZED) { |
| 537 Initialize(); | 496 Initialize(); |
| 538 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); | 497 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 } | 593 } |
| 635 | 594 |
| 636 virtual void FinishCode(Handle<Code> code) { | 595 virtual void FinishCode(Handle<Code> code) { |
| 637 code->set_stub_info(MinorKey()); | 596 code->set_stub_info(MinorKey()); |
| 638 } | 597 } |
| 639 | 598 |
| 640 friend class CodeGenerator; | 599 friend class CodeGenerator; |
| 641 }; | 600 }; |
| 642 | 601 |
| 643 | 602 |
| 644 class ICCompareStub: public PlatformCodeStub { | 603 class ICCompareStub: public CodeStub { |
| 645 public: | 604 public: |
| 646 ICCompareStub(Token::Value op, | 605 ICCompareStub(Token::Value op, |
| 647 CompareIC::State left, | 606 CompareIC::State left, |
| 648 CompareIC::State right, | 607 CompareIC::State right, |
| 649 CompareIC::State handler) | 608 CompareIC::State handler) |
| 650 : op_(op), | 609 : op_(op), |
| 651 left_(left), | 610 left_(left), |
| 652 right_(right), | 611 right_(right), |
| 653 state_(handler) { | 612 state_(handler) { |
| 654 ASSERT(Token::IsCompareOp(op)); | 613 ASSERT(Token::IsCompareOp(op)); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 virtual bool UseSpecialCache() { return state_ == CompareIC::KNOWN_OBJECTS; } | 659 virtual bool UseSpecialCache() { return state_ == CompareIC::KNOWN_OBJECTS; } |
| 701 | 660 |
| 702 Token::Value op_; | 661 Token::Value op_; |
| 703 CompareIC::State left_; | 662 CompareIC::State left_; |
| 704 CompareIC::State right_; | 663 CompareIC::State right_; |
| 705 CompareIC::State state_; | 664 CompareIC::State state_; |
| 706 Handle<Map> known_map_; | 665 Handle<Map> known_map_; |
| 707 }; | 666 }; |
| 708 | 667 |
| 709 | 668 |
| 710 class CEntryStub : public PlatformCodeStub { | 669 class CEntryStub : public CodeStub { |
| 711 public: | 670 public: |
| 712 explicit CEntryStub(int result_size, | 671 explicit CEntryStub(int result_size, |
| 713 SaveFPRegsMode save_doubles = kDontSaveFPRegs) | 672 SaveFPRegsMode save_doubles = kDontSaveFPRegs) |
| 714 : result_size_(result_size), save_doubles_(save_doubles) { } | 673 : result_size_(result_size), save_doubles_(save_doubles) { } |
| 715 | 674 |
| 716 void Generate(MacroAssembler* masm); | 675 void Generate(MacroAssembler* masm); |
| 717 | 676 |
| 718 // The version of this stub that doesn't save doubles is generated ahead of | 677 // The version of this stub that doesn't save doubles is generated ahead of |
| 719 // time, so it's OK to call it from other stubs that can't cope with GC during | 678 // time, so it's OK to call it from other stubs that can't cope with GC during |
| 720 // their code generation. On machines that always have gp registers (x64) we | 679 // their code generation. On machines that always have gp registers (x64) we |
| (...skipping 13 matching lines...) Expand all Loading... |
| 734 const int result_size_; | 693 const int result_size_; |
| 735 SaveFPRegsMode save_doubles_; | 694 SaveFPRegsMode save_doubles_; |
| 736 | 695 |
| 737 Major MajorKey() { return CEntry; } | 696 Major MajorKey() { return CEntry; } |
| 738 int MinorKey(); | 697 int MinorKey(); |
| 739 | 698 |
| 740 bool NeedsImmovableCode(); | 699 bool NeedsImmovableCode(); |
| 741 }; | 700 }; |
| 742 | 701 |
| 743 | 702 |
| 744 class JSEntryStub : public PlatformCodeStub { | 703 class JSEntryStub : public CodeStub { |
| 745 public: | 704 public: |
| 746 JSEntryStub() { } | 705 JSEntryStub() { } |
| 747 | 706 |
| 748 void Generate(MacroAssembler* masm) { GenerateBody(masm, false); } | 707 void Generate(MacroAssembler* masm) { GenerateBody(masm, false); } |
| 749 | 708 |
| 750 protected: | 709 protected: |
| 751 void GenerateBody(MacroAssembler* masm, bool is_construct); | 710 void GenerateBody(MacroAssembler* masm, bool is_construct); |
| 752 | 711 |
| 753 private: | 712 private: |
| 754 Major MajorKey() { return JSEntry; } | 713 Major MajorKey() { return JSEntry; } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 768 | 727 |
| 769 private: | 728 private: |
| 770 int MinorKey() { return 1; } | 729 int MinorKey() { return 1; } |
| 771 | 730 |
| 772 virtual void PrintName(StringStream* stream) { | 731 virtual void PrintName(StringStream* stream) { |
| 773 stream->Add("JSConstructEntryStub"); | 732 stream->Add("JSConstructEntryStub"); |
| 774 } | 733 } |
| 775 }; | 734 }; |
| 776 | 735 |
| 777 | 736 |
| 778 class ArgumentsAccessStub: public PlatformCodeStub { | 737 class ArgumentsAccessStub: public CodeStub { |
| 779 public: | 738 public: |
| 780 enum Type { | 739 enum Type { |
| 781 READ_ELEMENT, | 740 READ_ELEMENT, |
| 782 NEW_NON_STRICT_FAST, | 741 NEW_NON_STRICT_FAST, |
| 783 NEW_NON_STRICT_SLOW, | 742 NEW_NON_STRICT_SLOW, |
| 784 NEW_STRICT | 743 NEW_STRICT |
| 785 }; | 744 }; |
| 786 | 745 |
| 787 explicit ArgumentsAccessStub(Type type) : type_(type) { } | 746 explicit ArgumentsAccessStub(Type type) : type_(type) { } |
| 788 | 747 |
| 789 private: | 748 private: |
| 790 Type type_; | 749 Type type_; |
| 791 | 750 |
| 792 Major MajorKey() { return ArgumentsAccess; } | 751 Major MajorKey() { return ArgumentsAccess; } |
| 793 int MinorKey() { return type_; } | 752 int MinorKey() { return type_; } |
| 794 | 753 |
| 795 void Generate(MacroAssembler* masm); | 754 void Generate(MacroAssembler* masm); |
| 796 void GenerateReadElement(MacroAssembler* masm); | 755 void GenerateReadElement(MacroAssembler* masm); |
| 797 void GenerateNewStrict(MacroAssembler* masm); | 756 void GenerateNewStrict(MacroAssembler* masm); |
| 798 void GenerateNewNonStrictFast(MacroAssembler* masm); | 757 void GenerateNewNonStrictFast(MacroAssembler* masm); |
| 799 void GenerateNewNonStrictSlow(MacroAssembler* masm); | 758 void GenerateNewNonStrictSlow(MacroAssembler* masm); |
| 800 | 759 |
| 801 virtual void PrintName(StringStream* stream); | 760 virtual void PrintName(StringStream* stream); |
| 802 }; | 761 }; |
| 803 | 762 |
| 804 | 763 |
| 805 class RegExpExecStub: public PlatformCodeStub { | 764 class RegExpExecStub: public CodeStub { |
| 806 public: | 765 public: |
| 807 RegExpExecStub() { } | 766 RegExpExecStub() { } |
| 808 | 767 |
| 809 private: | 768 private: |
| 810 Major MajorKey() { return RegExpExec; } | 769 Major MajorKey() { return RegExpExec; } |
| 811 int MinorKey() { return 0; } | 770 int MinorKey() { return 0; } |
| 812 | 771 |
| 813 void Generate(MacroAssembler* masm); | 772 void Generate(MacroAssembler* masm); |
| 814 }; | 773 }; |
| 815 | 774 |
| 816 | 775 |
| 817 class RegExpConstructResultStub: public PlatformCodeStub { | 776 class RegExpConstructResultStub: public CodeStub { |
| 818 public: | 777 public: |
| 819 RegExpConstructResultStub() { } | 778 RegExpConstructResultStub() { } |
| 820 | 779 |
| 821 private: | 780 private: |
| 822 Major MajorKey() { return RegExpConstructResult; } | 781 Major MajorKey() { return RegExpConstructResult; } |
| 823 int MinorKey() { return 0; } | 782 int MinorKey() { return 0; } |
| 824 | 783 |
| 825 void Generate(MacroAssembler* masm); | 784 void Generate(MacroAssembler* masm); |
| 826 }; | 785 }; |
| 827 | 786 |
| 828 | 787 |
| 829 class CallFunctionStub: public PlatformCodeStub { | 788 class CallFunctionStub: public CodeStub { |
| 830 public: | 789 public: |
| 831 CallFunctionStub(int argc, CallFunctionFlags flags) | 790 CallFunctionStub(int argc, CallFunctionFlags flags) |
| 832 : argc_(argc), flags_(flags) { } | 791 : argc_(argc), flags_(flags) { } |
| 833 | 792 |
| 834 void Generate(MacroAssembler* masm); | 793 void Generate(MacroAssembler* masm); |
| 835 | 794 |
| 836 virtual void FinishCode(Handle<Code> code) { | 795 virtual void FinishCode(Handle<Code> code) { |
| 837 code->set_has_function_cache(RecordCallTarget()); | 796 code->set_has_function_cache(RecordCallTarget()); |
| 838 } | 797 } |
| 839 | 798 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 860 bool ReceiverMightBeImplicit() { | 819 bool ReceiverMightBeImplicit() { |
| 861 return (flags_ & RECEIVER_MIGHT_BE_IMPLICIT) != 0; | 820 return (flags_ & RECEIVER_MIGHT_BE_IMPLICIT) != 0; |
| 862 } | 821 } |
| 863 | 822 |
| 864 bool RecordCallTarget() { | 823 bool RecordCallTarget() { |
| 865 return (flags_ & RECORD_CALL_TARGET) != 0; | 824 return (flags_ & RECORD_CALL_TARGET) != 0; |
| 866 } | 825 } |
| 867 }; | 826 }; |
| 868 | 827 |
| 869 | 828 |
| 870 class CallConstructStub: public PlatformCodeStub { | 829 class CallConstructStub: public CodeStub { |
| 871 public: | 830 public: |
| 872 explicit CallConstructStub(CallFunctionFlags flags) : flags_(flags) {} | 831 explicit CallConstructStub(CallFunctionFlags flags) : flags_(flags) {} |
| 873 | 832 |
| 874 void Generate(MacroAssembler* masm); | 833 void Generate(MacroAssembler* masm); |
| 875 | 834 |
| 876 virtual void FinishCode(Handle<Code> code) { | 835 virtual void FinishCode(Handle<Code> code) { |
| 877 code->set_has_function_cache(RecordCallTarget()); | 836 code->set_has_function_cache(RecordCallTarget()); |
| 878 } | 837 } |
| 879 | 838 |
| 880 private: | 839 private: |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 } | 1010 } |
| 1052 | 1011 |
| 1053 private: | 1012 private: |
| 1054 MacroAssembler* masm_; | 1013 MacroAssembler* masm_; |
| 1055 bool previous_allow_; | 1014 bool previous_allow_; |
| 1056 | 1015 |
| 1057 DISALLOW_COPY_AND_ASSIGN(AllowStubCallsScope); | 1016 DISALLOW_COPY_AND_ASSIGN(AllowStubCallsScope); |
| 1058 }; | 1017 }; |
| 1059 | 1018 |
| 1060 | 1019 |
| 1061 class KeyedLoadDictionaryElementStub : public PlatformCodeStub { | 1020 class KeyedLoadElementStub : public CodeStub { |
| 1062 public: | 1021 public: |
| 1063 KeyedLoadDictionaryElementStub() {} | 1022 explicit KeyedLoadElementStub(ElementsKind elements_kind) |
| 1023 : elements_kind_(elements_kind) |
| 1024 { } |
| 1064 | 1025 |
| 1065 Major MajorKey() { return KeyedLoadElement; } | 1026 Major MajorKey() { return KeyedLoadElement; } |
| 1066 int MinorKey() { return DICTIONARY_ELEMENTS; } | 1027 int MinorKey() { return elements_kind_; } |
| 1067 | 1028 |
| 1068 void Generate(MacroAssembler* masm); | 1029 void Generate(MacroAssembler* masm); |
| 1069 | 1030 |
| 1070 private: | 1031 private: |
| 1071 DISALLOW_COPY_AND_ASSIGN(KeyedLoadDictionaryElementStub); | 1032 ElementsKind elements_kind_; |
| 1033 |
| 1034 DISALLOW_COPY_AND_ASSIGN(KeyedLoadElementStub); |
| 1072 }; | 1035 }; |
| 1073 | 1036 |
| 1074 | 1037 |
| 1075 class KeyedLoadFastElementStub : public HydrogenCodeStub { | 1038 class KeyedStoreElementStub : public CodeStub { |
| 1076 public: | |
| 1077 KeyedLoadFastElementStub(bool is_js_array, ElementsKind elements_kind) { | |
| 1078 bit_field_ = ElementsKindBits::encode(elements_kind) | | |
| 1079 IsJSArrayBits::encode(is_js_array); | |
| 1080 } | |
| 1081 | |
| 1082 Major MajorKey() { return KeyedLoadElement; } | |
| 1083 int MinorKey() { return bit_field_; } | |
| 1084 | |
| 1085 bool is_js_array() const { | |
| 1086 return IsJSArrayBits::decode(bit_field_); | |
| 1087 } | |
| 1088 | |
| 1089 ElementsKind elements_kind() const { | |
| 1090 return ElementsKindBits::decode(bit_field_); | |
| 1091 } | |
| 1092 | |
| 1093 virtual Handle<Code> GenerateCode(); | |
| 1094 | |
| 1095 virtual void InitializeInterfaceDescriptor( | |
| 1096 Isolate* isolate, | |
| 1097 CodeStubInterfaceDescriptor* descriptor); | |
| 1098 | |
| 1099 private: | |
| 1100 class IsJSArrayBits: public BitField<bool, 8, 1> {}; | |
| 1101 class ElementsKindBits: public BitField<ElementsKind, 0, 8> {}; | |
| 1102 uint32_t bit_field_; | |
| 1103 | |
| 1104 DISALLOW_COPY_AND_ASSIGN(KeyedLoadFastElementStub); | |
| 1105 }; | |
| 1106 | |
| 1107 | |
| 1108 class KeyedStoreElementStub : public PlatformCodeStub { | |
| 1109 public: | 1039 public: |
| 1110 KeyedStoreElementStub(bool is_js_array, | 1040 KeyedStoreElementStub(bool is_js_array, |
| 1111 ElementsKind elements_kind, | 1041 ElementsKind elements_kind, |
| 1112 KeyedAccessGrowMode grow_mode) | 1042 KeyedAccessGrowMode grow_mode) |
| 1113 : is_js_array_(is_js_array), | 1043 : is_js_array_(is_js_array), |
| 1114 elements_kind_(elements_kind), | 1044 elements_kind_(elements_kind), |
| 1115 grow_mode_(grow_mode), | 1045 grow_mode_(grow_mode), |
| 1116 fp_registers_(CanUseFPRegisters()) { } | 1046 fp_registers_(CanUseFPRegisters()) { } |
| 1117 | 1047 |
| 1118 Major MajorKey() { return KeyedStoreElement; } | 1048 Major MajorKey() { return KeyedStoreElement; } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1133 | 1063 |
| 1134 bool is_js_array_; | 1064 bool is_js_array_; |
| 1135 ElementsKind elements_kind_; | 1065 ElementsKind elements_kind_; |
| 1136 KeyedAccessGrowMode grow_mode_; | 1066 KeyedAccessGrowMode grow_mode_; |
| 1137 bool fp_registers_; | 1067 bool fp_registers_; |
| 1138 | 1068 |
| 1139 DISALLOW_COPY_AND_ASSIGN(KeyedStoreElementStub); | 1069 DISALLOW_COPY_AND_ASSIGN(KeyedStoreElementStub); |
| 1140 }; | 1070 }; |
| 1141 | 1071 |
| 1142 | 1072 |
| 1143 class ToBooleanStub: public PlatformCodeStub { | 1073 class ToBooleanStub: public CodeStub { |
| 1144 public: | 1074 public: |
| 1145 enum Type { | 1075 enum Type { |
| 1146 UNDEFINED, | 1076 UNDEFINED, |
| 1147 BOOLEAN, | 1077 BOOLEAN, |
| 1148 NULL_TYPE, | 1078 NULL_TYPE, |
| 1149 SMI, | 1079 SMI, |
| 1150 SPEC_OBJECT, | 1080 SPEC_OBJECT, |
| 1151 STRING, | 1081 STRING, |
| 1152 HEAP_NUMBER, | 1082 HEAP_NUMBER, |
| 1153 NUMBER_OF_TYPES | 1083 NUMBER_OF_TYPES |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 Type type, | 1133 Type type, |
| 1204 Heap::RootListIndex value, | 1134 Heap::RootListIndex value, |
| 1205 bool result); | 1135 bool result); |
| 1206 void GenerateTypeTransition(MacroAssembler* masm); | 1136 void GenerateTypeTransition(MacroAssembler* masm); |
| 1207 | 1137 |
| 1208 Register tos_; | 1138 Register tos_; |
| 1209 Types types_; | 1139 Types types_; |
| 1210 }; | 1140 }; |
| 1211 | 1141 |
| 1212 | 1142 |
| 1213 class ElementsTransitionAndStoreStub : public PlatformCodeStub { | 1143 class ElementsTransitionAndStoreStub : public CodeStub { |
| 1214 public: | 1144 public: |
| 1215 ElementsTransitionAndStoreStub(ElementsKind from, | 1145 ElementsTransitionAndStoreStub(ElementsKind from, |
| 1216 ElementsKind to, | 1146 ElementsKind to, |
| 1217 bool is_jsarray, | 1147 bool is_jsarray, |
| 1218 StrictModeFlag strict_mode, | 1148 StrictModeFlag strict_mode, |
| 1219 KeyedAccessGrowMode grow_mode) | 1149 KeyedAccessGrowMode grow_mode) |
| 1220 : from_(from), | 1150 : from_(from), |
| 1221 to_(to), | 1151 to_(to), |
| 1222 is_jsarray_(is_jsarray), | 1152 is_jsarray_(is_jsarray), |
| 1223 strict_mode_(strict_mode), | 1153 strict_mode_(strict_mode), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1244 ElementsKind from_; | 1174 ElementsKind from_; |
| 1245 ElementsKind to_; | 1175 ElementsKind to_; |
| 1246 bool is_jsarray_; | 1176 bool is_jsarray_; |
| 1247 StrictModeFlag strict_mode_; | 1177 StrictModeFlag strict_mode_; |
| 1248 KeyedAccessGrowMode grow_mode_; | 1178 KeyedAccessGrowMode grow_mode_; |
| 1249 | 1179 |
| 1250 DISALLOW_COPY_AND_ASSIGN(ElementsTransitionAndStoreStub); | 1180 DISALLOW_COPY_AND_ASSIGN(ElementsTransitionAndStoreStub); |
| 1251 }; | 1181 }; |
| 1252 | 1182 |
| 1253 | 1183 |
| 1254 class StoreArrayLiteralElementStub : public PlatformCodeStub { | 1184 class StoreArrayLiteralElementStub : public CodeStub { |
| 1255 public: | 1185 public: |
| 1256 StoreArrayLiteralElementStub() | 1186 StoreArrayLiteralElementStub() |
| 1257 : fp_registers_(CanUseFPRegisters()) { } | 1187 : fp_registers_(CanUseFPRegisters()) { } |
| 1258 | 1188 |
| 1259 private: | 1189 private: |
| 1260 class FPRegisters: public BitField<bool, 0, 1> {}; | 1190 class FPRegisters: public BitField<bool, 0, 1> {}; |
| 1261 | 1191 |
| 1262 Major MajorKey() { return StoreArrayLiteralElement; } | 1192 Major MajorKey() { return StoreArrayLiteralElement; } |
| 1263 int MinorKey() { return FPRegisters::encode(fp_registers_); } | 1193 int MinorKey() { return FPRegisters::encode(fp_registers_); } |
| 1264 | 1194 |
| 1265 void Generate(MacroAssembler* masm); | 1195 void Generate(MacroAssembler* masm); |
| 1266 | 1196 |
| 1267 bool fp_registers_; | 1197 bool fp_registers_; |
| 1268 | 1198 |
| 1269 DISALLOW_COPY_AND_ASSIGN(StoreArrayLiteralElementStub); | 1199 DISALLOW_COPY_AND_ASSIGN(StoreArrayLiteralElementStub); |
| 1270 }; | 1200 }; |
| 1271 | 1201 |
| 1272 | 1202 |
| 1273 class ProfileEntryHookStub : public PlatformCodeStub { | 1203 class ProfileEntryHookStub : public CodeStub { |
| 1274 public: | 1204 public: |
| 1275 explicit ProfileEntryHookStub() {} | 1205 explicit ProfileEntryHookStub() {} |
| 1276 | 1206 |
| 1277 // The profile entry hook function is not allowed to cause a GC. | 1207 // The profile entry hook function is not allowed to cause a GC. |
| 1278 virtual bool SometimesSetsUpAFrame() { return false; } | 1208 virtual bool SometimesSetsUpAFrame() { return false; } |
| 1279 | 1209 |
| 1280 // Generates a call to the entry hook if it's enabled. | 1210 // Generates a call to the entry hook if it's enabled. |
| 1281 static void MaybeCallEntryHook(MacroAssembler* masm); | 1211 static void MaybeCallEntryHook(MacroAssembler* masm); |
| 1282 | 1212 |
| 1283 // Sets or unsets the entry hook function. Returns true on success, | 1213 // Sets or unsets the entry hook function. Returns true on success, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1298 | 1228 |
| 1299 // The current function entry hook. | 1229 // The current function entry hook. |
| 1300 static FunctionEntryHook entry_hook_; | 1230 static FunctionEntryHook entry_hook_; |
| 1301 | 1231 |
| 1302 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); | 1232 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); |
| 1303 }; | 1233 }; |
| 1304 | 1234 |
| 1305 } } // namespace v8::internal | 1235 } } // namespace v8::internal |
| 1306 | 1236 |
| 1307 #endif // V8_CODE_STUBS_H_ | 1237 #endif // V8_CODE_STUBS_H_ |
| OLD | NEW |