| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 int32_t offset_; // valid if rm_ == no_reg | 461 int32_t offset_; // valid if rm_ == no_reg |
| 462 ShiftOp shift_op_; | 462 ShiftOp shift_op_; |
| 463 int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg | 463 int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg |
| 464 AddrMode am_; // bits P, U, and W | 464 AddrMode am_; // bits P, U, and W |
| 465 | 465 |
| 466 friend class Assembler; | 466 friend class Assembler; |
| 467 }; | 467 }; |
| 468 | 468 |
| 469 // CpuFeatures keeps track of which features are supported by the target CPU. | 469 // CpuFeatures keeps track of which features are supported by the target CPU. |
| 470 // Supported features must be enabled by a Scope before use. | 470 // Supported features must be enabled by a Scope before use. |
| 471 class CpuFeatures { | 471 class CpuFeatures : public AllStatic { |
| 472 public: | 472 public: |
| 473 // Detect features of the target CPU. Set safe defaults if the serializer | 473 // Detect features of the target CPU. Set safe defaults if the serializer |
| 474 // is enabled (snapshots must be portable). | 474 // is enabled (snapshots must be portable). |
| 475 void Probe(bool portable); | 475 static void Probe(); |
| 476 | 476 |
| 477 // Check whether a feature is supported by the target CPU. | 477 // Check whether a feature is supported by the target CPU. |
| 478 bool IsSupported(CpuFeature f) const { | 478 static bool IsSupported(CpuFeature f) { |
| 479 ASSERT(initialized_); |
| 479 if (f == VFP3 && !FLAG_enable_vfp3) return false; | 480 if (f == VFP3 && !FLAG_enable_vfp3) return false; |
| 480 return (supported_ & (1u << f)) != 0; | 481 return (supported_ & (1u << f)) != 0; |
| 481 } | 482 } |
| 482 | 483 |
| 484 #ifdef DEBUG |
| 483 // Check whether a feature is currently enabled. | 485 // Check whether a feature is currently enabled. |
| 484 bool IsEnabled(CpuFeature f) const { | 486 static bool IsEnabled(CpuFeature f) { |
| 485 return (enabled_ & (1u << f)) != 0; | 487 ASSERT(initialized_); |
| 488 Isolate* isolate = Isolate::UncheckedCurrent(); |
| 489 if (isolate == NULL) { |
| 490 // When no isolate is available, work as if we're running in |
| 491 // release mode. |
| 492 return IsSupported(f); |
| 493 } |
| 494 unsigned enabled = static_cast<unsigned>(isolate->enabled_cpu_features()); |
| 495 return (enabled & (1u << f)) != 0; |
| 486 } | 496 } |
| 497 #endif |
| 487 | 498 |
| 488 // Enable a specified feature within a scope. | 499 // Enable a specified feature within a scope. |
| 489 class Scope BASE_EMBEDDED { | 500 class Scope BASE_EMBEDDED { |
| 490 #ifdef DEBUG | 501 #ifdef DEBUG |
| 491 public: | 502 public: |
| 492 explicit Scope(CpuFeature f) | 503 explicit Scope(CpuFeature f) { |
| 493 : cpu_features_(Isolate::Current()->cpu_features()), | 504 unsigned mask = 1u << f; |
| 494 isolate_(Isolate::Current()) { | 505 ASSERT(CpuFeatures::IsSupported(f)); |
| 495 ASSERT(cpu_features_->IsSupported(f)); | |
| 496 ASSERT(!Serializer::enabled() || | 506 ASSERT(!Serializer::enabled() || |
| 497 (cpu_features_->found_by_runtime_probing_ & (1u << f)) == 0); | 507 (CpuFeatures::found_by_runtime_probing_ & mask) == 0); |
| 498 old_enabled_ = cpu_features_->enabled_; | 508 isolate_ = Isolate::UncheckedCurrent(); |
| 499 cpu_features_->enabled_ |= 1u << f; | 509 old_enabled_ = 0; |
| 510 if (isolate_ != NULL) { |
| 511 old_enabled_ = static_cast<unsigned>(isolate_->enabled_cpu_features()); |
| 512 isolate_->set_enabled_cpu_features(old_enabled_ | mask); |
| 513 } |
| 500 } | 514 } |
| 501 ~Scope() { | 515 ~Scope() { |
| 502 ASSERT_EQ(Isolate::Current(), isolate_); | 516 ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_); |
| 503 cpu_features_->enabled_ = old_enabled_; | 517 if (isolate_ != NULL) { |
| 518 isolate_->set_enabled_cpu_features(old_enabled_); |
| 519 } |
| 504 } | 520 } |
| 505 private: | 521 private: |
| 522 Isolate* isolate_; |
| 506 unsigned old_enabled_; | 523 unsigned old_enabled_; |
| 507 CpuFeatures* cpu_features_; | |
| 508 Isolate* isolate_; | |
| 509 #else | 524 #else |
| 510 public: | 525 public: |
| 511 explicit Scope(CpuFeature f) {} | 526 explicit Scope(CpuFeature f) {} |
| 512 #endif | 527 #endif |
| 513 }; | 528 }; |
| 514 | 529 |
| 530 class TryForceFeatureScope BASE_EMBEDDED { |
| 531 public: |
| 532 explicit TryForceFeatureScope(CpuFeature f) |
| 533 : old_supported_(CpuFeatures::supported_) { |
| 534 if (CanForce()) { |
| 535 CpuFeatures::supported_ |= (1u << f); |
| 536 } |
| 537 } |
| 538 |
| 539 ~TryForceFeatureScope() { |
| 540 if (CanForce()) { |
| 541 CpuFeatures::supported_ = old_supported_; |
| 542 } |
| 543 } |
| 544 |
| 545 private: |
| 546 static bool CanForce() { |
| 547 // It's only safe to temporarily force support of CPU features |
| 548 // when there's only a single isolate, which is guaranteed when |
| 549 // the serializer is enabled. |
| 550 return Serializer::enabled(); |
| 551 } |
| 552 |
| 553 const unsigned old_supported_; |
| 554 }; |
| 555 |
| 515 private: | 556 private: |
| 516 CpuFeatures(); | 557 #ifdef DEBUG |
| 517 | 558 static bool initialized_; |
| 518 unsigned supported_; | 559 #endif |
| 519 unsigned enabled_; | 560 static unsigned supported_; |
| 520 unsigned found_by_runtime_probing_; | 561 static unsigned found_by_runtime_probing_; |
| 521 | |
| 522 friend class Isolate; | |
| 523 | 562 |
| 524 DISALLOW_COPY_AND_ASSIGN(CpuFeatures); | 563 DISALLOW_COPY_AND_ASSIGN(CpuFeatures); |
| 525 }; | 564 }; |
| 526 | 565 |
| 527 | 566 |
| 528 extern const Instr kMovLrPc; | 567 extern const Instr kMovLrPc; |
| 529 extern const Instr kLdrPCMask; | 568 extern const Instr kLdrPCMask; |
| 530 extern const Instr kLdrPCPattern; | 569 extern const Instr kLdrPCPattern; |
| 531 extern const Instr kBlxRegMask; | 570 extern const Instr kBlxRegMask; |
| 532 extern const Instr kBlxRegPattern; | 571 extern const Instr kBlxRegPattern; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 557 // for a detailed comment on the layout (globals.h). | 596 // for a detailed comment on the layout (globals.h). |
| 558 // | 597 // |
| 559 // If the provided buffer is NULL, the assembler allocates and grows its own | 598 // If the provided buffer is NULL, the assembler allocates and grows its own |
| 560 // buffer, and buffer_size determines the initial buffer size. The buffer is | 599 // buffer, and buffer_size determines the initial buffer size. The buffer is |
| 561 // owned by the assembler and deallocated upon destruction of the assembler. | 600 // owned by the assembler and deallocated upon destruction of the assembler. |
| 562 // | 601 // |
| 563 // If the provided buffer is not NULL, the assembler uses the provided buffer | 602 // If the provided buffer is not NULL, the assembler uses the provided buffer |
| 564 // for code generation and assumes its size to be buffer_size. If the buffer | 603 // for code generation and assumes its size to be buffer_size. If the buffer |
| 565 // is too small, a fatal error occurs. No deallocation of the buffer is done | 604 // is too small, a fatal error occurs. No deallocation of the buffer is done |
| 566 // upon destruction of the assembler. | 605 // upon destruction of the assembler. |
| 567 Assembler(void* buffer, int buffer_size); | 606 Assembler(Isolate* isolate, void* buffer, int buffer_size); |
| 568 ~Assembler(); | 607 ~Assembler(); |
| 569 | 608 |
| 570 // Overrides the default provided by FLAG_debug_code. | 609 // Overrides the default provided by FLAG_debug_code. |
| 571 void set_emit_debug_code(bool value) { emit_debug_code_ = value; } | 610 void set_emit_debug_code(bool value) { emit_debug_code_ = value; } |
| 572 | 611 |
| 573 // GetCode emits any pending (non-emitted) code and fills the descriptor | 612 // GetCode emits any pending (non-emitted) code and fills the descriptor |
| 574 // desc. GetCode() is idempotent; it returns the same result if no other | 613 // desc. GetCode() is idempotent; it returns the same result if no other |
| 575 // Assembler functions are invoked in between GetCode() calls. | 614 // Assembler functions are invoked in between GetCode() calls. |
| 576 void GetCode(CodeDesc* desc); | 615 void GetCode(CodeDesc* desc); |
| 577 | 616 |
| (...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 public: | 1349 public: |
| 1311 explicit EnsureSpace(Assembler* assembler) { | 1350 explicit EnsureSpace(Assembler* assembler) { |
| 1312 assembler->CheckBuffer(); | 1351 assembler->CheckBuffer(); |
| 1313 } | 1352 } |
| 1314 }; | 1353 }; |
| 1315 | 1354 |
| 1316 | 1355 |
| 1317 } } // namespace v8::internal | 1356 } } // namespace v8::internal |
| 1318 | 1357 |
| 1319 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1358 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
| OLD | NEW |