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 |