| 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 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 inline void set_sib(ScaleFactor scale, Register index, Register base); | 345 inline void set_sib(ScaleFactor scale, Register index, Register base); |
| 346 | 346 |
| 347 // Adds operand displacement fields (offsets added to the memory address). | 347 // Adds operand displacement fields (offsets added to the memory address). |
| 348 // Needs to be called after set_sib, not before it. | 348 // Needs to be called after set_sib, not before it. |
| 349 inline void set_disp8(int disp); | 349 inline void set_disp8(int disp); |
| 350 inline void set_disp32(int disp); | 350 inline void set_disp32(int disp); |
| 351 | 351 |
| 352 friend class Assembler; | 352 friend class Assembler; |
| 353 }; | 353 }; |
| 354 | 354 |
| 355 class AssemblerData:public BasicAssemblerData { |
| 356 public: |
| 357 // A previously allocated buffer of kMinimalBufferSize bytes, or NULL. |
| 358 byte* spare_buffer_; |
| 359 // CPU features |
| 360 uint64_t supported_; |
| 361 uint64_t enabled_; |
| 362 uint64_t found_by_runtime_probing_; |
| 363 private: |
| 364 AssemblerData(); |
| 365 ~AssemblerData() { delete spare_buffer_; } |
| 366 friend class Assembler; |
| 367 DISALLOW_COPY_AND_ASSIGN(AssemblerData); |
| 368 }; |
| 355 | 369 |
| 356 // CpuFeatures keeps track of which features are supported by the target CPU. | 370 // CpuFeatures keeps track of which features are supported by the target CPU. |
| 357 // Supported features must be enabled by a Scope before use. | 371 // Supported features must be enabled by a Scope before use. |
| 358 // Example: | 372 // Example: |
| 359 // if (CpuFeatures::IsSupported(SSE3)) { | 373 // if (CpuFeatures::IsSupported(SSE3)) { |
| 360 // CpuFeatures::Scope fscope(SSE3); | 374 // CpuFeatures::Scope fscope(SSE3); |
| 361 // // Generate SSE3 floating point code. | 375 // // Generate SSE3 floating point code. |
| 362 // } else { | 376 // } else { |
| 363 // // Generate standard x87 or SSE2 floating point code. | 377 // // Generate standard x87 or SSE2 floating point code. |
| 364 // } | 378 // } |
| 365 class CpuFeatures : public AllStatic { | 379 class CpuFeatures : public AllStatic { |
| 366 public: | 380 public: |
| 367 // Detect features of the target CPU. Set safe defaults if the serializer | 381 // Detect features of the target CPU. Set safe defaults if the serializer |
| 368 // is enabled (snapshots must be portable). | 382 // is enabled (snapshots must be portable). |
| 369 static void Probe(); | 383 static void Probe(); |
| 370 // Check whether a feature is supported by the target CPU. | 384 // Check whether a feature is supported by the target CPU. |
| 371 static bool IsSupported(CpuFeature f) { | 385 static bool IsSupported(CpuFeature f) { |
| 372 if (f == SSE2 && !FLAG_enable_sse2) return false; | 386 if (f == SSE2 && !FLAG_enable_sse2) return false; |
| 373 if (f == SSE3 && !FLAG_enable_sse3) return false; | 387 if (f == SSE3 && !FLAG_enable_sse3) return false; |
| 374 if (f == CMOV && !FLAG_enable_cmov) return false; | 388 if (f == CMOV && !FLAG_enable_cmov) return false; |
| 375 if (f == RDTSC && !FLAG_enable_rdtsc) return false; | 389 if (f == RDTSC && !FLAG_enable_rdtsc) return false; |
| 376 if (f == SAHF && !FLAG_enable_sahf) return false; | 390 if (f == SAHF && !FLAG_enable_sahf) return false; |
| 377 return (supported_ & (V8_UINT64_C(1) << f)) != 0; | 391 return (v8_context()->assembler_data_->supported_ & |
| 392 (V8_UINT64_C(1) << f)) != 0; |
| 378 } | 393 } |
| 379 // Check whether a feature is currently enabled. | 394 // Check whether a feature is currently enabled. |
| 380 static bool IsEnabled(CpuFeature f) { | 395 static bool IsEnabled(CpuFeature f) { |
| 381 return (enabled_ & (V8_UINT64_C(1) << f)) != 0; | 396 return (v8_context()->assembler_data_->enabled_ & |
| 397 (V8_UINT64_C(1) << f)) != 0; |
| 382 } | 398 } |
| 383 // Enable a specified feature within a scope. | 399 // Enable a specified feature within a scope. |
| 384 class Scope BASE_EMBEDDED { | 400 class Scope BASE_EMBEDDED { |
| 385 #ifdef DEBUG | 401 #ifdef DEBUG |
| 386 public: | 402 public: |
| 387 explicit Scope(CpuFeature f) { | 403 explicit Scope(CpuFeature f) { |
| 388 uint64_t mask = (V8_UINT64_C(1) << f); | 404 uint64_t mask = (V8_UINT64_C(1) << f); |
| 405 AssemblerData* const data = v8_context()->assembler_data_; |
| 389 ASSERT(CpuFeatures::IsSupported(f)); | 406 ASSERT(CpuFeatures::IsSupported(f)); |
| 390 ASSERT(!Serializer::enabled() || (found_by_runtime_probing_ & mask) == 0); | 407 ASSERT(!Serializer::enabled() || |
| 391 old_enabled_ = CpuFeatures::enabled_; | 408 (data->found_by_runtime_probing_ & mask) == 0); |
| 392 CpuFeatures::enabled_ |= mask; | 409 old_enabled_ = data->enabled_; |
| 410 data->enabled_ |= mask; |
| 393 } | 411 } |
| 394 ~Scope() { CpuFeatures::enabled_ = old_enabled_; } | 412 ~Scope() { v8_context()->assembler_data_->enabled_ = old_enabled_; } |
| 395 private: | 413 private: |
| 396 uint64_t old_enabled_; | 414 uint64_t old_enabled_; |
| 397 #else | 415 #else |
| 398 public: | 416 public: |
| 399 explicit Scope(CpuFeature f) {} | 417 explicit Scope(CpuFeature f) {} |
| 400 #endif | 418 #endif |
| 401 }; | 419 }; |
| 402 private: | 420 private: |
| 403 // Safe defaults include SSE2 and CMOV for X64. It is always available, if | 421 // Safe defaults include SSE2 and CMOV for X64. It is always available, if |
| 404 // anyone checks, but they shouldn't need to check. | 422 // anyone checks, but they shouldn't need to check. |
| 405 static const uint64_t kDefaultCpuFeatures = (1 << SSE2 | 1 << CMOV); | 423 static const uint64_t kDefaultCpuFeatures = (1 << SSE2 | 1 << CMOV); |
| 406 static uint64_t supported_; | 424 friend class AssemblerData; |
| 407 static uint64_t enabled_; | |
| 408 static uint64_t found_by_runtime_probing_; | |
| 409 }; | 425 }; |
| 410 | 426 |
| 411 | 427 |
| 412 class Assembler : public Malloced { | 428 class Assembler : public Malloced { |
| 413 private: | 429 private: |
| 414 // We check before assembling an instruction that there is sufficient | 430 // We check before assembling an instruction that there is sufficient |
| 415 // space to write an instruction and its relocation information. | 431 // space to write an instruction and its relocation information. |
| 416 // The relocation writer's position must be kGap bytes above the end of | 432 // The relocation writer's position must be kGap bytes above the end of |
| 417 // the generated instructions. This leaves enough space for the | 433 // the generated instructions. This leaves enough space for the |
| 418 // longest possible x64 instruction, 15 bytes, and the longest possible | 434 // longest possible x64 instruction, 15 bytes, and the longest possible |
| (...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1341 friend class CodePatcher; | 1357 friend class CodePatcher; |
| 1342 friend class EnsureSpace; | 1358 friend class EnsureSpace; |
| 1343 friend class RegExpMacroAssemblerX64; | 1359 friend class RegExpMacroAssemblerX64; |
| 1344 | 1360 |
| 1345 // Code buffer: | 1361 // Code buffer: |
| 1346 // The buffer into which code and relocation info are generated. | 1362 // The buffer into which code and relocation info are generated. |
| 1347 byte* buffer_; | 1363 byte* buffer_; |
| 1348 int buffer_size_; | 1364 int buffer_size_; |
| 1349 // True if the assembler owns the buffer, false if buffer is external. | 1365 // True if the assembler owns the buffer, false if buffer is external. |
| 1350 bool own_buffer_; | 1366 bool own_buffer_; |
| 1351 // A previously allocated buffer of kMinimalBufferSize bytes, or NULL. | |
| 1352 static byte* spare_buffer_; | |
| 1353 | 1367 |
| 1354 // code generation | 1368 // code generation |
| 1355 byte* pc_; // the program counter; moves forward | 1369 byte* pc_; // the program counter; moves forward |
| 1356 RelocInfoWriter reloc_info_writer; | 1370 RelocInfoWriter reloc_info_writer; |
| 1357 | 1371 |
| 1358 List< Handle<Code> > code_targets_; | 1372 List< Handle<Code> > code_targets_; |
| 1359 // push-pop elimination | 1373 // push-pop elimination |
| 1360 byte* last_pc_; | 1374 byte* last_pc_; |
| 1361 | 1375 |
| 1362 // source position information | 1376 // source position information |
| 1363 int current_statement_position_; | 1377 int current_statement_position_; |
| 1364 int current_position_; | 1378 int current_position_; |
| 1365 int written_statement_position_; | 1379 int written_statement_position_; |
| 1366 int written_position_; | 1380 int written_position_; |
| 1381 |
| 1382 static void PostConstruct(); |
| 1383 static void PreDestroy(); |
| 1384 friend class V8Context; |
| 1367 }; | 1385 }; |
| 1368 | 1386 |
| 1369 | 1387 |
| 1370 // Helper class that ensures that there is enough space for generating | 1388 // Helper class that ensures that there is enough space for generating |
| 1371 // instructions and relocation information. The constructor makes | 1389 // instructions and relocation information. The constructor makes |
| 1372 // sure that there is enough space and (in debug mode) the destructor | 1390 // sure that there is enough space and (in debug mode) the destructor |
| 1373 // checks that we did not generate too much. | 1391 // checks that we did not generate too much. |
| 1374 class EnsureSpace BASE_EMBEDDED { | 1392 class EnsureSpace BASE_EMBEDDED { |
| 1375 public: | 1393 public: |
| 1376 explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { | 1394 explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1390 private: | 1408 private: |
| 1391 Assembler* assembler_; | 1409 Assembler* assembler_; |
| 1392 #ifdef DEBUG | 1410 #ifdef DEBUG |
| 1393 int space_before_; | 1411 int space_before_; |
| 1394 #endif | 1412 #endif |
| 1395 }; | 1413 }; |
| 1396 | 1414 |
| 1397 } } // namespace v8::internal | 1415 } } // namespace v8::internal |
| 1398 | 1416 |
| 1399 #endif // V8_X64_ASSEMBLER_X64_H_ | 1417 #endif // V8_X64_ASSEMBLER_X64_H_ |
| OLD | NEW |