| 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 are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // 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 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 | 439 |
| 440 // CpuFeatures keeps track of which features are supported by the target CPU. | 440 // CpuFeatures keeps track of which features are supported by the target CPU. |
| 441 // Supported features must be enabled by a Scope before use. | 441 // Supported features must be enabled by a Scope before use. |
| 442 // Example: | 442 // Example: |
| 443 // if (CpuFeatures::IsSupported(SSE2)) { | 443 // if (CpuFeatures::IsSupported(SSE2)) { |
| 444 // CpuFeatures::Scope fscope(SSE2); | 444 // CpuFeatures::Scope fscope(SSE2); |
| 445 // // Generate SSE2 floating point code. | 445 // // Generate SSE2 floating point code. |
| 446 // } else { | 446 // } else { |
| 447 // // Generate standard x87 floating point code. | 447 // // Generate standard x87 floating point code. |
| 448 // } | 448 // } |
| 449 class CpuFeatures : public AllStatic { | 449 class CpuFeatures { |
| 450 public: | 450 public: |
| 451 // Detect features of the target CPU. Set safe defaults if the serializer | 451 // Detect features of the target CPU. If the portable flag is set, |
| 452 // is enabled (snapshots must be portable). | 452 // the method sets safe defaults if the serializer is enabled |
| 453 static void Probe(); | 453 // (snapshots must be portable). |
| 454 void Probe(bool portable); |
| 455 void Clear() { supported_ = 0; } |
| 454 | 456 |
| 455 // Check whether a feature is supported by the target CPU. | 457 // Check whether a feature is supported by the target CPU. |
| 456 static bool IsSupported(CpuFeature f) { | 458 bool IsSupported(CpuFeature f) const { |
| 457 ASSERT(initialized_); | |
| 458 if (f == SSE2 && !FLAG_enable_sse2) return false; | 459 if (f == SSE2 && !FLAG_enable_sse2) return false; |
| 459 if (f == SSE3 && !FLAG_enable_sse3) return false; | 460 if (f == SSE3 && !FLAG_enable_sse3) return false; |
| 460 if (f == SSE4_1 && !FLAG_enable_sse4_1) return false; | 461 if (f == SSE4_1 && !FLAG_enable_sse4_1) return false; |
| 461 if (f == CMOV && !FLAG_enable_cmov) return false; | 462 if (f == CMOV && !FLAG_enable_cmov) return false; |
| 462 if (f == RDTSC && !FLAG_enable_rdtsc) return false; | 463 if (f == RDTSC && !FLAG_enable_rdtsc) return false; |
| 463 return (supported_ & (static_cast<uint64_t>(1) << f)) != 0; | 464 return (supported_ & (static_cast<uint64_t>(1) << f)) != 0; |
| 464 } | 465 } |
| 465 | |
| 466 #ifdef DEBUG | |
| 467 // Check whether a feature is currently enabled. | 466 // Check whether a feature is currently enabled. |
| 468 static bool IsEnabled(CpuFeature f) { | 467 bool IsEnabled(CpuFeature f) const { |
| 469 ASSERT(initialized_); | 468 return (enabled_ & (static_cast<uint64_t>(1) << f)) != 0; |
| 470 Isolate* isolate = Isolate::UncheckedCurrent(); | |
| 471 if (isolate == NULL) { | |
| 472 // When no isolate is available, work as if we're running in | |
| 473 // release mode. | |
| 474 return IsSupported(f); | |
| 475 } | |
| 476 uint64_t enabled = isolate->enabled_cpu_features(); | |
| 477 return (enabled & (static_cast<uint64_t>(1) << f)) != 0; | |
| 478 } | 469 } |
| 479 #endif | |
| 480 | |
| 481 // Enable a specified feature within a scope. | 470 // Enable a specified feature within a scope. |
| 482 class Scope BASE_EMBEDDED { | 471 class Scope BASE_EMBEDDED { |
| 483 #ifdef DEBUG | 472 #ifdef DEBUG |
| 484 public: | 473 public: |
| 485 explicit Scope(CpuFeature f) { | 474 explicit Scope(CpuFeature f) |
| 475 : cpu_features_(Isolate::Current()->cpu_features()), |
| 476 isolate_(Isolate::Current()) { |
| 486 uint64_t mask = static_cast<uint64_t>(1) << f; | 477 uint64_t mask = static_cast<uint64_t>(1) << f; |
| 487 ASSERT(CpuFeatures::IsSupported(f)); | 478 ASSERT(cpu_features_->IsSupported(f)); |
| 488 ASSERT(!Serializer::enabled() || | 479 ASSERT(!Serializer::enabled() || |
| 489 (CpuFeatures::found_by_runtime_probing_ & mask) == 0); | 480 (cpu_features_->found_by_runtime_probing_ & mask) == 0); |
| 490 isolate_ = Isolate::UncheckedCurrent(); | 481 old_enabled_ = cpu_features_->enabled_; |
| 491 old_enabled_ = 0; | 482 cpu_features_->enabled_ |= mask; |
| 492 if (isolate_ != NULL) { | |
| 493 old_enabled_ = isolate_->enabled_cpu_features(); | |
| 494 isolate_->set_enabled_cpu_features(old_enabled_ | mask); | |
| 495 } | |
| 496 } | 483 } |
| 497 ~Scope() { | 484 ~Scope() { |
| 498 ASSERT_EQ(Isolate::UncheckedCurrent(), isolate_); | 485 ASSERT_EQ(Isolate::Current(), isolate_); |
| 499 if (isolate_ != NULL) { | 486 cpu_features_->enabled_ = old_enabled_; |
| 500 isolate_->set_enabled_cpu_features(old_enabled_); | |
| 501 } | |
| 502 } | 487 } |
| 503 private: | 488 private: |
| 489 uint64_t old_enabled_; |
| 490 CpuFeatures* cpu_features_; |
| 504 Isolate* isolate_; | 491 Isolate* isolate_; |
| 505 uint64_t old_enabled_; | |
| 506 #else | 492 #else |
| 507 public: | 493 public: |
| 508 explicit Scope(CpuFeature f) {} | 494 explicit Scope(CpuFeature f) {} |
| 509 #endif | 495 #endif |
| 510 }; | 496 }; |
| 511 | 497 |
| 512 class TryForceFeatureScope BASE_EMBEDDED { | 498 private: |
| 513 public: | 499 CpuFeatures(); |
| 514 explicit TryForceFeatureScope(CpuFeature f) | |
| 515 : old_supported_(CpuFeatures::supported_) { | |
| 516 if (CanForce()) { | |
| 517 CpuFeatures::supported_ |= (static_cast<uint64_t>(1) << f); | |
| 518 } | |
| 519 } | |
| 520 | 500 |
| 521 ~TryForceFeatureScope() { | 501 uint64_t supported_; |
| 522 if (CanForce()) { | 502 uint64_t enabled_; |
| 523 CpuFeatures::supported_ = old_supported_; | 503 uint64_t found_by_runtime_probing_; |
| 524 } | |
| 525 } | |
| 526 | 504 |
| 527 private: | 505 friend class Isolate; |
| 528 static bool CanForce() { | |
| 529 // It's only safe to temporarily force support of CPU features | |
| 530 // when there's only a single isolate, which is guaranteed when | |
| 531 // the serializer is enabled. | |
| 532 return Serializer::enabled(); | |
| 533 } | |
| 534 | |
| 535 const uint64_t old_supported_; | |
| 536 }; | |
| 537 | |
| 538 private: | |
| 539 #ifdef DEBUG | |
| 540 static bool initialized_; | |
| 541 #endif | |
| 542 static uint64_t supported_; | |
| 543 static uint64_t found_by_runtime_probing_; | |
| 544 | 506 |
| 545 DISALLOW_COPY_AND_ASSIGN(CpuFeatures); | 507 DISALLOW_COPY_AND_ASSIGN(CpuFeatures); |
| 546 }; | 508 }; |
| 547 | 509 |
| 548 | 510 |
| 549 class Assembler : public AssemblerBase { | 511 class Assembler : public AssemblerBase { |
| 550 private: | 512 private: |
| 551 // We check before assembling an instruction that there is sufficient | 513 // We check before assembling an instruction that there is sufficient |
| 552 // space to write an instruction and its relocation information. | 514 // space to write an instruction and its relocation information. |
| 553 // The relocation writer's position must be kGap bytes above the end of | 515 // The relocation writer's position must be kGap bytes above the end of |
| (...skipping 12 matching lines...) Expand all Loading... |
| 566 // for a detailed comment on the layout (globals.h). | 528 // for a detailed comment on the layout (globals.h). |
| 567 // | 529 // |
| 568 // If the provided buffer is NULL, the assembler allocates and grows its own | 530 // If the provided buffer is NULL, the assembler allocates and grows its own |
| 569 // buffer, and buffer_size determines the initial buffer size. The buffer is | 531 // buffer, and buffer_size determines the initial buffer size. The buffer is |
| 570 // owned by the assembler and deallocated upon destruction of the assembler. | 532 // owned by the assembler and deallocated upon destruction of the assembler. |
| 571 // | 533 // |
| 572 // If the provided buffer is not NULL, the assembler uses the provided buffer | 534 // If the provided buffer is not NULL, the assembler uses the provided buffer |
| 573 // for code generation and assumes its size to be buffer_size. If the buffer | 535 // for code generation and assumes its size to be buffer_size. If the buffer |
| 574 // is too small, a fatal error occurs. No deallocation of the buffer is done | 536 // is too small, a fatal error occurs. No deallocation of the buffer is done |
| 575 // upon destruction of the assembler. | 537 // upon destruction of the assembler. |
| 576 // TODO(vitalyr): the assembler does not need an isolate. | 538 Assembler(void* buffer, int buffer_size); |
| 577 Assembler(Isolate* isolate, void* buffer, int buffer_size); | |
| 578 ~Assembler(); | 539 ~Assembler(); |
| 579 | 540 |
| 580 // Overrides the default provided by FLAG_debug_code. | 541 // Overrides the default provided by FLAG_debug_code. |
| 581 void set_emit_debug_code(bool value) { emit_debug_code_ = value; } | 542 void set_emit_debug_code(bool value) { emit_debug_code_ = value; } |
| 582 | 543 |
| 583 // GetCode emits any pending (non-emitted) code and fills the descriptor | 544 // GetCode emits any pending (non-emitted) code and fills the descriptor |
| 584 // desc. GetCode() is idempotent; it returns the same result if no other | 545 // desc. GetCode() is idempotent; it returns the same result if no other |
| 585 // Assembler functions are invoked in between GetCode() calls. | 546 // Assembler functions are invoked in between GetCode() calls. |
| 586 void GetCode(CodeDesc* desc); | 547 void GetCode(CodeDesc* desc); |
| 587 | 548 |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1150 private: | 1111 private: |
| 1151 Assembler* assembler_; | 1112 Assembler* assembler_; |
| 1152 #ifdef DEBUG | 1113 #ifdef DEBUG |
| 1153 int space_before_; | 1114 int space_before_; |
| 1154 #endif | 1115 #endif |
| 1155 }; | 1116 }; |
| 1156 | 1117 |
| 1157 } } // namespace v8::internal | 1118 } } // namespace v8::internal |
| 1158 | 1119 |
| 1159 #endif // V8_IA32_ASSEMBLER_IA32_H_ | 1120 #endif // V8_IA32_ASSEMBLER_IA32_H_ |
| OLD | NEW |