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