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

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

Issue 24744002: Pattern match on generated code to find edge counters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/constants_arm.h" 8 #include "vm/constants_arm.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/instructions.h" 10 #include "vm/instructions.h"
11 #include "vm/object.h" 11 #include "vm/object.h"
12 12
13 namespace dart { 13 namespace dart {
14 14
15 CallPattern::CallPattern(uword pc, const Code& code) 15 CallPattern::CallPattern(uword pc, const Code& code)
16 : end_(reinterpret_cast<uword*>(pc)), 16 : object_pool_(Array::Handle(code.ObjectPool())),
17 end_(reinterpret_cast<uword*>(pc)),
18 args_desc_load_end_(NULL),
19 ic_data_load_end_(NULL),
17 target_address_pool_index_(-1), 20 target_address_pool_index_(-1),
18 args_desc_load_end_(-1),
19 args_desc_(Array::Handle()), 21 args_desc_(Array::Handle()),
20 ic_data_load_end_(-1), 22 ic_data_(ICData::Handle()) {
21 ic_data_(ICData::Handle()),
22 object_pool_(Array::Handle(code.ObjectPool())) {
23 ASSERT(code.ContainsInstructionAt(pc)); 23 ASSERT(code.ContainsInstructionAt(pc));
24 ASSERT(Back(1) == 0xe12fff3e); // Last instruction: blx lr 24 ASSERT(*(end_ - 1) == 0xe12fff3e); // Last instruction: blx lr
25 Register reg; 25 Register reg;
26 ic_data_load_end_ = 26 ic_data_load_end_ =
27 DecodeLoadWordFromPool(1, &reg, &target_address_pool_index_); 27 InstructionPattern::DecodeLoadWordFromPool(end_ - 1,
28 &reg,
29 &target_address_pool_index_);
28 ASSERT(reg == LR); 30 ASSERT(reg == LR);
29 } 31 }
30 32
31 33
32 uword CallPattern::Back(int n) const { 34 // Decodes a load sequence ending at 'end' (the last instruction of the load
33 ASSERT(n > 0); 35 // sequence is the instruction before the one at end). Returns a pointer to
34 return *(end_ - n); 36 // the first instruction in the sequence. Returns the register being loaded
35 } 37 // and the loaded object in the output parameters 'reg' and 'obj'
36 38 // respectively.
37 39 const uword* InstructionPattern::DecodeLoadObject(const uword* end,
38 // Decodes a load sequence ending at end. Returns the register being loaded and 40 const Array& object_pool,
39 // the loaded object. 41 Register* reg,
40 // Returns the location of the load sequence, counting the number of 42 Object* obj) {
41 // instructions back from the end of the call pattern. 43 uword instr = *(end - 1);
42 int CallPattern::DecodeLoadObject(int end, Register* reg, Object* obj) {
43 ASSERT(end > 0);
44 uword instr = Back(end + 1);
45 if ((instr & 0xfff00000) == 0xe5900000) { // ldr reg, [reg, #+offset] 44 if ((instr & 0xfff00000) == 0xe5900000) { // ldr reg, [reg, #+offset]
46 int index = 0; 45 intptr_t index = 0;
47 end = DecodeLoadWordFromPool(end, reg, &index); 46 end = DecodeLoadWordFromPool(end, reg, &index);
48 *obj = object_pool_.At(index); 47 *obj = object_pool.At(index);
49 } else { 48 } else {
50 int value = 0; 49 intptr_t value = 0;
51 end = DecodeLoadWordImmediate(end, reg, &value); 50 end = DecodeLoadWordImmediate(end, reg, &value);
52 *obj = reinterpret_cast<RawObject*>(value); 51 *obj = reinterpret_cast<RawObject*>(value);
53 } 52 }
54 return end; 53 return end;
55 } 54 }
56 55
57 56
58 // Decodes a load sequence ending at end. Returns the register being loaded and 57 // Decodes a load sequence ending at 'end' (the last instruction of the load
59 // the loaded immediate value. 58 // sequence is the instruction before the one at end). Returns a pointer to
60 // Returns the location of the load sequence, counting the number of 59 // the first instruction in the sequence. Returns the register being loaded
61 // instructions back from the end of the call pattern. 60 // and the loaded immediate value in the output parameters 'reg' and 'value'
62 int CallPattern::DecodeLoadWordImmediate(int end, Register* reg, int* value) { 61 // respectively.
63 ASSERT(end > 0); 62 const uword* InstructionPattern::DecodeLoadWordImmediate(const uword* end,
64 uword instr = Back(++end); 63 Register* reg,
65 int imm = 0; 64 intptr_t* value) {
65 uword instr = *(--end);
66 intptr_t imm = 0;
66 if ((instr & 0xfff00000) == 0xe3400000) { // movt reg, #imm_hi 67 if ((instr & 0xfff00000) == 0xe3400000) { // movt reg, #imm_hi
67 imm |= (instr & 0xf0000) << 12; 68 imm |= (instr & 0xf0000) << 12;
68 imm |= (instr & 0xfff) << 16; 69 imm |= (instr & 0xfff) << 16;
69 instr = Back(++end); 70 instr = *(--end);
70 } 71 }
71 ASSERT((instr & 0xfff00000) == 0xe3000000); // movw reg, #imm_lo 72 ASSERT((instr & 0xfff00000) == 0xe3000000); // movw reg, #imm_lo
72 imm |= (instr & 0xf0000) >> 4; 73 imm |= (instr & 0xf0000) >> 4;
73 imm |= instr & 0xfff; 74 imm |= instr & 0xfff;
74 *reg = static_cast<Register>((instr & 0xf000) >> 12); 75 *reg = static_cast<Register>((instr & 0xf000) >> 12);
75 *value = imm; 76 *value = imm;
76 return end; 77 return end;
77 } 78 }
78 79
79 80
80 // Decodes a load sequence ending at end. Returns the register being loaded and 81 // Decodes a load sequence ending at 'end' (the last instruction of the load
81 // the index in the pool being read from. 82 // sequence is the instruction before the one at end). Returns a pointer to
82 // Returns the location of the load sequence, counting the number of 83 // the first instruction in the sequence. Returns the register being loaded
83 // instructions back from the end of the call pattern. 84 // and the index in the pool being read from in the output parameters 'reg'
84 int CallPattern::DecodeLoadWordFromPool(int end, Register* reg, int* index) { 85 // and 'index' respectively.
85 ASSERT(end > 0); 86 const uword* InstructionPattern::DecodeLoadWordFromPool(const uword* end,
86 uword instr = Back(++end); 87 Register* reg,
87 int offset = 0; 88 intptr_t* index) {
89 uword instr = *(--end);
90 intptr_t offset = 0;
88 if ((instr & 0xffff0000) == 0xe59a0000) { // ldr reg, [pp, #+offset] 91 if ((instr & 0xffff0000) == 0xe59a0000) { // ldr reg, [pp, #+offset]
89 offset = instr & 0xfff; 92 offset = instr & 0xfff;
90 *reg = static_cast<Register>((instr & 0xf000) >> 12); 93 *reg = static_cast<Register>((instr & 0xf000) >> 12);
91 } else { 94 } else {
92 ASSERT((instr & 0xfff00000) == 0xe5900000); // ldr reg, [reg, #+offset] 95 ASSERT((instr & 0xfff00000) == 0xe5900000); // ldr reg, [reg, #+offset]
93 offset = instr & 0xfff; 96 offset = instr & 0xfff;
94 instr = Back(++end); 97 instr = *(--end);
95 if ((instr & 0xffff0000) == 0xe28a0000) { // add reg, pp, shifter_op 98 if ((instr & 0xffff0000) == 0xe28a0000) { // add reg, pp, shifter_op
96 const int rot = (instr & 0xf00) >> 7; 99 const intptr_t rot = (instr & 0xf00) >> 7;
97 const int imm8 = instr & 0xff; 100 const intptr_t imm8 = instr & 0xff;
98 offset += (imm8 >> rot) | (imm8 << (32 - rot)); 101 offset += (imm8 >> rot) | (imm8 << (32 - rot));
99 *reg = static_cast<Register>((instr & 0xf000) >> 12); 102 *reg = static_cast<Register>((instr & 0xf000) >> 12);
100 } else { 103 } else {
101 ASSERT((instr & 0xffff0000) == 0xe08a0000); // add reg, pp, reg 104 ASSERT((instr & 0xffff0000) == 0xe08a0000); // add reg, pp, reg
102 end = DecodeLoadWordImmediate(end, reg, &offset); 105 end = DecodeLoadWordImmediate(end, reg, &offset);
103 } 106 }
104 } 107 }
105 offset += kHeapObjectTag; 108 offset += kHeapObjectTag;
106 ASSERT(Utils::IsAligned(offset, 4)); 109 ASSERT(Utils::IsAligned(offset, 4));
107 *index = (offset - Array::data_offset())/4; 110 *index = (offset - Array::data_offset()) / 4;
108 return end; 111 return end;
109 } 112 }
110 113
111 114
112 RawICData* CallPattern::IcData() { 115 RawICData* CallPattern::IcData() {
113 if (ic_data_.IsNull()) { 116 if (ic_data_.IsNull()) {
114 Register reg; 117 Register reg;
115 args_desc_load_end_ = DecodeLoadObject(ic_data_load_end_, &reg, &ic_data_); 118 args_desc_load_end_ =
119 InstructionPattern::DecodeLoadObject(ic_data_load_end_,
120 object_pool_,
121 &reg,
122 &ic_data_);
116 ASSERT(reg == R5); 123 ASSERT(reg == R5);
117 } 124 }
118 return ic_data_.raw(); 125 return ic_data_.raw();
119 } 126 }
120 127
121 128
122 RawArray* CallPattern::ClosureArgumentsDescriptor() { 129 RawArray* CallPattern::ClosureArgumentsDescriptor() {
123 if (args_desc_.IsNull()) { 130 if (args_desc_.IsNull()) {
124 IcData(); // Loading of the ic_data must be decoded first, if not already. 131 IcData(); // Loading of the ic_data must be decoded first, if not already.
125 Register reg; 132 Register reg;
126 DecodeLoadObject(args_desc_load_end_, &reg, &args_desc_); 133 InstructionPattern::DecodeLoadObject(args_desc_load_end_,
134 object_pool_,
135 &reg,
136 &args_desc_);
127 ASSERT(reg == R4); 137 ASSERT(reg == R4);
128 } 138 }
129 return args_desc_.raw(); 139 return args_desc_.raw();
130 } 140 }
131 141
132 142
133 uword CallPattern::TargetAddress() const { 143 uword CallPattern::TargetAddress() const {
134 ASSERT(target_address_pool_index_ >= 0); 144 ASSERT(target_address_pool_index_ >= 0);
135 const Object& target_address = 145 const Object& target_address =
136 Object::Handle(object_pool_.At(target_address_pool_index_)); 146 Object::Handle(object_pool_.At(target_address_pool_index_));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 uword movw_ip = 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff); 201 uword movw_ip = 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff);
192 uword movt_ip = 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff); 202 uword movt_ip = 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff);
193 *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = movw_ip; 203 *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = movw_ip;
194 *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = movt_ip; 204 *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = movt_ip;
195 CPU::FlushICache(pc_, 2 * Instr::kInstrSize); 205 CPU::FlushICache(pc_, 2 * Instr::kInstrSize);
196 } 206 }
197 207
198 } // namespace dart 208 } // namespace dart
199 209
200 #endif // defined TARGET_ARCH_ARM 210 #endif // defined TARGET_ARCH_ARM
201
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698