Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: runtime/vm/instructions_x64.cc

Issue 22825023: Uses an object pool on x64 (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/cpu.h" 8 #include "vm/cpu.h"
9 #include "vm/instructions.h" 9 #include "vm/instructions.h"
10 #include "vm/object.h" 10 #include "vm/object.h"
11 11
12 namespace dart { 12 namespace dart {
13 13
14 int InstructionPattern::IndexFromPPLoad(uword start) {
15 uint8_t which = *reinterpret_cast<uint8_t*>(start);
16 if ((which & 0xF0) == 0x90) {
17 int32_t offset = *reinterpret_cast<int32_t*>(start + 1);
18 offset += kHeapObjectTag;
19 return (offset - Array::data_offset())/kWordSize;
20 } else {
21 ASSERT((which & 0xF0) == 0x50);
22 int32_t offset = *reinterpret_cast<int8_t*>(start + 1);
23 offset += kHeapObjectTag;
24 return (offset - Array::data_offset())/kWordSize;
25 }
26 }
27
28
14 bool InstructionPattern::TestBytesWith(const int* data, int num_bytes) const { 29 bool InstructionPattern::TestBytesWith(const int* data, int num_bytes) const {
15 ASSERT(data != NULL); 30 ASSERT(data != NULL);
16 const uint8_t* byte_array = reinterpret_cast<const uint8_t*>(start_); 31 const uint8_t* byte_array = reinterpret_cast<const uint8_t*>(start_);
17 for (int i = 0; i < num_bytes; i++) { 32 for (int i = 0; i < num_bytes; i++) {
18 // Skip comparison for data[i] < 0. 33 // Skip comparison for data[i] < 0.
19 if ((data[i] >= 0) && (byte_array[i] != (0xFF & data[i]))) { 34 if ((data[i] >= 0) && (byte_array[i] != (0xFF & data[i]))) {
20 return false; 35 return false;
21 } 36 }
22 } 37 }
23 return true; 38 return true;
24 } 39 }
25 40
26 41
27 uword CallOrJumpPattern::TargetAddress() const { 42 uword CallPattern::TargetAddress() const {
28 ASSERT(IsValid()); 43 ASSERT(IsValid());
29 return *reinterpret_cast<uword*>(start() + 2); 44 return *reinterpret_cast<uword*>(start() + 2);
30 } 45 }
31 46
32 47
33 void CallOrJumpPattern::SetTargetAddress(uword target) const { 48 void CallPattern::SetTargetAddress(uword target) const {
34 ASSERT(IsValid()); 49 ASSERT(IsValid());
35 *reinterpret_cast<uword*>(start() + 2) = target; 50 *reinterpret_cast<uword*>(start() + 2) = target;
36 CPU::FlushICache(start() + 2, kWordSize); 51 CPU::FlushICache(start() + 2, kWordSize);
37 } 52 }
38 53
39 54
40 const int* CallPattern::pattern() const { 55 const int* CallPattern::pattern() const {
41 // movq $target, TMP 56 // movq $target, TMP
42 // callq *TMP 57 // callq *TMP
43 static const int kCallPattern[kLengthInBytes] = 58 static const int kCallPattern[kLengthInBytes] =
44 {0x49, 0xBB, -1, -1, -1, -1, -1, -1, -1, -1, 0x41, 0xFF, 0xD3}; 59 {0x49, 0xBB, -1, -1, -1, -1, -1, -1, -1, -1, 0x41, 0xFF, 0xD3};
45 return kCallPattern; 60 return kCallPattern;
46 } 61 }
47 62
48 63
64 uword JumpPattern::TargetAddress() const {
65 ASSERT(IsValid());
66 int index = InstructionPattern::IndexFromPPLoad(start() + 2);
67 return reinterpret_cast<uword>(object_pool_.At(index));
68 }
69
70
71 void JumpPattern::SetTargetAddress(uword target) const {
72 ASSERT(IsValid());
73 int index = InstructionPattern::IndexFromPPLoad(start() + 2);
74 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target));
75 object_pool_.SetAt(index, smi);
76 // No need to flush the instruction cache, since the code is not modified.
77 }
78
79
49 const int* JumpPattern::pattern() const { 80 const int* JumpPattern::pattern() const {
50 // movq $target, TMP 81 // 00: 4d 8b 9d imm32 mov R11, [R13 + off]
51 // jmpq TMP 82 // OR:
83 // 00: 4d 8b 5d imm8 mov R11, [R13 + off]
84 // 04: 0f 1f 00 nop
85 // 07: 41 ff e3 jmpq R11
52 static const int kJumpPattern[kLengthInBytes] = 86 static const int kJumpPattern[kLengthInBytes] =
53 {0x49, 0xBB, -1, -1, -1, -1, -1, -1, -1, -1, 0x41, 0xFF, 0xE3}; 87 {0x4D, 0x8B, -1, -1, -1, -1, -1, 0x41, 0xFF, 0xE3};
54 return kJumpPattern; 88 return kJumpPattern;
55 } 89 }
56 90
57 91
58 void ShortCallPattern::SetTargetAddress(uword target) const { 92 void ShortCallPattern::SetTargetAddress(uword target) const {
59 ASSERT(IsValid()); 93 ASSERT(IsValid());
60 *reinterpret_cast<uint32_t*>(start() + 1) = target - start() - kLengthInBytes; 94 *reinterpret_cast<uint32_t*>(start() + 1) = target - start() - kLengthInBytes;
61 CPU::FlushICache(start() + 1, kWordSize); 95 CPU::FlushICache(start() + 1, kWordSize);
62 } 96 }
63 97
64 98
65 const int* ShortCallPattern::pattern() const { 99 const int* ShortCallPattern::pattern() const {
66 static const int kCallPattern[kLengthInBytes] = {0xE8, -1, -1, -1, -1}; 100 static const int kCallPattern[kLengthInBytes] = {0xE8, -1, -1, -1, -1};
67 return kCallPattern; 101 return kCallPattern;
68 } 102 }
69 103
70 } // namespace dart 104 } // namespace dart
71 105
72 #endif // defined TARGET_ARCH_X64 106 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698