| 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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 private: | 341 private: |
| 342 int data_; | 342 int data_; |
| 343 | 343 |
| 344 class TypeField: public BitField<Type, 0, 2> {}; | 344 class TypeField: public BitField<Type, 0, 2> {}; |
| 345 class NextField: public BitField<int, 2, 32-2> {}; | 345 class NextField: public BitField<int, 2, 32-2> {}; |
| 346 | 346 |
| 347 void init(Label* L, Type type); | 347 void init(Label* L, Type type); |
| 348 }; | 348 }; |
| 349 | 349 |
| 350 | 350 |
| 351 class AssemblerData:public BasicAssemblerData { |
| 352 public: |
| 353 // A previously allocated buffer of kMinimalBufferSize bytes, or NULL. |
| 354 byte* spare_buffer_; |
| 355 // CPU features |
| 356 uint64_t supported_; |
| 357 uint64_t enabled_; |
| 358 uint64_t found_by_runtime_probing_; |
| 359 private: |
| 360 AssemblerData() |
| 361 :BasicAssemblerData(), |
| 362 spare_buffer_(NULL), |
| 363 // Safe default is no features. |
| 364 supported_(0), |
| 365 enabled_(0), |
| 366 found_by_runtime_probing_(0) { |
| 367 } |
| 368 ~AssemblerData() { delete spare_buffer_; } |
| 369 friend class Assembler; |
| 370 DISALLOW_COPY_AND_ASSIGN(AssemblerData); |
| 371 }; |
| 351 | 372 |
| 352 // CpuFeatures keeps track of which features are supported by the target CPU. | 373 // CpuFeatures keeps track of which features are supported by the target CPU. |
| 353 // Supported features must be enabled by a Scope before use. | 374 // Supported features must be enabled by a Scope before use. |
| 354 // Example: | 375 // Example: |
| 355 // if (CpuFeatures::IsSupported(SSE2)) { | 376 // if (CpuFeatures::IsSupported(SSE2)) { |
| 356 // CpuFeatures::Scope fscope(SSE2); | 377 // CpuFeatures::Scope fscope(SSE2); |
| 357 // // Generate SSE2 floating point code. | 378 // // Generate SSE2 floating point code. |
| 358 // } else { | 379 // } else { |
| 359 // // Generate standard x87 floating point code. | 380 // // Generate standard x87 floating point code. |
| 360 // } | 381 // } |
| 361 class CpuFeatures : public AllStatic { | 382 class CpuFeatures : public AllStatic { |
| 362 public: | 383 public: |
| 363 // Detect features of the target CPU. Set safe defaults if the serializer | 384 // Detect features of the target CPU. Set safe defaults if the serializer |
| 364 // is enabled (snapshots must be portable). | 385 // is enabled (snapshots must be portable). |
| 365 static void Probe(); | 386 static void Probe(); |
| 366 // Check whether a feature is supported by the target CPU. | 387 // Check whether a feature is supported by the target CPU. |
| 367 static bool IsSupported(CpuFeature f) { | 388 static bool IsSupported(CpuFeature f) { |
| 368 if (f == SSE2 && !FLAG_enable_sse2) return false; | 389 if (f == SSE2 && !FLAG_enable_sse2) return false; |
| 369 if (f == SSE3 && !FLAG_enable_sse3) return false; | 390 if (f == SSE3 && !FLAG_enable_sse3) return false; |
| 370 if (f == CMOV && !FLAG_enable_cmov) return false; | 391 if (f == CMOV && !FLAG_enable_cmov) return false; |
| 371 if (f == RDTSC && !FLAG_enable_rdtsc) return false; | 392 if (f == RDTSC && !FLAG_enable_rdtsc) return false; |
| 372 return (supported_ & (static_cast<uint64_t>(1) << f)) != 0; | 393 return (v8_context()->assembler_data_->supported_ & |
| 394 (static_cast<uint64_t>(1) << f)) != 0; |
| 373 } | 395 } |
| 374 // Check whether a feature is currently enabled. | 396 // Check whether a feature is currently enabled. |
| 375 static bool IsEnabled(CpuFeature f) { | 397 static bool IsEnabled(CpuFeature f) { |
| 376 return (enabled_ & (static_cast<uint64_t>(1) << f)) != 0; | 398 return (v8_context()->assembler_data_->enabled_ & |
| 399 (static_cast<uint64_t>(1) << f)) != 0; |
| 377 } | 400 } |
| 378 // Enable a specified feature within a scope. | 401 // Enable a specified feature within a scope. |
| 379 class Scope BASE_EMBEDDED { | 402 class Scope BASE_EMBEDDED { |
| 380 #ifdef DEBUG | 403 #ifdef DEBUG |
| 381 public: | 404 public: |
| 382 explicit Scope(CpuFeature f) { | 405 explicit Scope(CpuFeature f) { |
| 383 uint64_t mask = static_cast<uint64_t>(1) << f; | 406 uint64_t mask = static_cast<uint64_t>(1) << f; |
| 384 ASSERT(CpuFeatures::IsSupported(f)); | 407 ASSERT(CpuFeatures::IsSupported(f)); |
| 385 ASSERT(!Serializer::enabled() || (found_by_runtime_probing_ & mask) == 0); | 408 AssemblerData* const data = v8_context()->assembler_data_; |
| 386 old_enabled_ = CpuFeatures::enabled_; | 409 ASSERT(!Serializer::enabled() || |
| 387 CpuFeatures::enabled_ |= mask; | 410 (data->found_by_runtime_probing_ & mask) == 0); |
| 411 old_enabled_ = data->enabled_; |
| 412 data->enabled_ |= mask; |
| 388 } | 413 } |
| 389 ~Scope() { CpuFeatures::enabled_ = old_enabled_; } | 414 ~Scope() { v8_context()->assembler_data_->enabled_ = old_enabled_; } |
| 390 private: | 415 private: |
| 391 uint64_t old_enabled_; | 416 uint64_t old_enabled_; |
| 392 #else | 417 #else |
| 393 public: | 418 public: |
| 394 explicit Scope(CpuFeature f) {} | 419 explicit Scope(CpuFeature f) {} |
| 395 #endif | 420 #endif |
| 396 }; | 421 }; |
| 397 private: | |
| 398 static uint64_t supported_; | |
| 399 static uint64_t enabled_; | |
| 400 static uint64_t found_by_runtime_probing_; | |
| 401 }; | 422 }; |
| 402 | 423 |
| 403 | 424 |
| 404 class Assembler : public Malloced { | 425 class Assembler : public Malloced { |
| 405 private: | 426 private: |
| 406 // We check before assembling an instruction that there is sufficient | 427 // We check before assembling an instruction that there is sufficient |
| 407 // space to write an instruction and its relocation information. | 428 // space to write an instruction and its relocation information. |
| 408 // The relocation writer's position must be kGap bytes above the end of | 429 // The relocation writer's position must be kGap bytes above the end of |
| 409 // the generated instructions. This leaves enough space for the | 430 // the generated instructions. This leaves enough space for the |
| 410 // longest possible ia32 instruction, 15 bytes, and the longest possible | 431 // longest possible ia32 instruction, 15 bytes, and the longest possible |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 | 867 |
| 847 friend class CodePatcher; | 868 friend class CodePatcher; |
| 848 friend class EnsureSpace; | 869 friend class EnsureSpace; |
| 849 | 870 |
| 850 // Code buffer: | 871 // Code buffer: |
| 851 // The buffer into which code and relocation info are generated. | 872 // The buffer into which code and relocation info are generated. |
| 852 byte* buffer_; | 873 byte* buffer_; |
| 853 int buffer_size_; | 874 int buffer_size_; |
| 854 // True if the assembler owns the buffer, false if buffer is external. | 875 // True if the assembler owns the buffer, false if buffer is external. |
| 855 bool own_buffer_; | 876 bool own_buffer_; |
| 856 // A previously allocated buffer of kMinimalBufferSize bytes, or NULL. | |
| 857 static byte* spare_buffer_; | |
| 858 | 877 |
| 859 // code generation | 878 // code generation |
| 860 byte* pc_; // the program counter; moves forward | 879 byte* pc_; // the program counter; moves forward |
| 861 RelocInfoWriter reloc_info_writer; | 880 RelocInfoWriter reloc_info_writer; |
| 862 | 881 |
| 863 // push-pop elimination | 882 // push-pop elimination |
| 864 byte* last_pc_; | 883 byte* last_pc_; |
| 865 | 884 |
| 866 // source position information | 885 // source position information |
| 867 int current_statement_position_; | 886 int current_statement_position_; |
| 868 int current_position_; | 887 int current_position_; |
| 869 int written_statement_position_; | 888 int written_statement_position_; |
| 870 int written_position_; | 889 int written_position_; |
| 890 |
| 891 static void PostConstruct(); |
| 892 static void PreDestroy(); |
| 893 friend class V8Context; |
| 871 }; | 894 }; |
| 872 | 895 |
| 873 | 896 |
| 874 // Helper class that ensures that there is enough space for generating | 897 // Helper class that ensures that there is enough space for generating |
| 875 // instructions and relocation information. The constructor makes | 898 // instructions and relocation information. The constructor makes |
| 876 // sure that there is enough space and (in debug mode) the destructor | 899 // sure that there is enough space and (in debug mode) the destructor |
| 877 // checks that we did not generate too much. | 900 // checks that we did not generate too much. |
| 878 class EnsureSpace BASE_EMBEDDED { | 901 class EnsureSpace BASE_EMBEDDED { |
| 879 public: | 902 public: |
| 880 explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { | 903 explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 894 private: | 917 private: |
| 895 Assembler* assembler_; | 918 Assembler* assembler_; |
| 896 #ifdef DEBUG | 919 #ifdef DEBUG |
| 897 int space_before_; | 920 int space_before_; |
| 898 #endif | 921 #endif |
| 899 }; | 922 }; |
| 900 | 923 |
| 901 } } // namespace v8::internal | 924 } } // namespace v8::internal |
| 902 | 925 |
| 903 #endif // V8_IA32_ASSEMBLER_IA32_H_ | 926 #endif // V8_IA32_ASSEMBLER_IA32_H_ |
| OLD | NEW |