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 |