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

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

Issue 10825236: Replace deopt stubs location/register shuffling with using deopt-info. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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/deopt_instructions.h" 5 #include "vm/deopt_instructions.h"
6 6
7 #include "vm/assembler_macros.h"
7 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
8 #include "vm/locations.h" 9 #include "vm/locations.h"
9 #include "vm/parser.h" 10 #include "vm/parser.h"
10 11
11 namespace dart { 12 namespace dart {
12 13
14 DeoptimizationContext::DeoptimizationContext(intptr_t* to_frame_start,
15 const Array& object_table,
16 intptr_t num_args)
17 : object_table_(object_table),
18 to_frame_(to_frame_start),
19 from_frame_(NULL),
20 from_frame_size_(0),
21 registers_copy_(NULL),
22 num_args_(num_args) {
23 Isolate* isolate = Isolate::Current();
24 from_frame_ = isolate->deopt_frame_copy();
25 from_frame_size_ = isolate->deopt_frame_copy_size();
26 registers_copy_ = isolate->deopt_registers_copy();
27 }
28
29
30 intptr_t* DeoptimizationContext::GetFromFpAddress() const {
31 return &from_frame_[from_frame_size_ - 1 - num_args_ - 1];
32 }
33
34
35 intptr_t* DeoptimizationContext::GetFromPcAddress() const {
36 return &from_frame_[from_frame_size_ - 1 - num_args_];
37 }
38
13 // Deoptimization instruction moving value from optimized frame at 39 // Deoptimization instruction moving value from optimized frame at
14 // 'from_index' to specified slots in the unoptimized frame. 40 // 'from_index' to specified slots in the unoptimized frame.
15 // 'from_index' represents the local count >= 0, first 41 // 'from_index' represents the slot index of the frame (0 being first argument)
16 // argument being 0. 42 // and accounts for saved return address, frame pointer and pc marker.
17 class DeoptStackSlotInstr : public DeoptInstr { 43 class DeoptStackSlotInstr : public DeoptInstr {
18 public: 44 public:
19 explicit DeoptStackSlotInstr(intptr_t from_index) 45 explicit DeoptStackSlotInstr(intptr_t from_index)
20 : stack_slot_index_(from_index) { 46 : stack_slot_index_(from_index) {
21 ASSERT(stack_slot_index_ >= 0); 47 ASSERT(stack_slot_index_ >= 0);
22 } 48 }
23 49
24 virtual intptr_t from_index() const { return stack_slot_index_; } 50 virtual intptr_t from_index() const { return stack_slot_index_; }
25 virtual DeoptInstr::Kind kind() const { return kCopyStackSlot; } 51 virtual DeoptInstr::Kind kind() const { return kCopyStackSlot; }
26 52
27 virtual const char* ToCString() const { 53 virtual const char* ToCString() const {
28 intptr_t len = OS::SNPrint(NULL, 0, "s%d", stack_slot_index_); 54 intptr_t len = OS::SNPrint(NULL, 0, "s%d", stack_slot_index_);
29 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 55 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
30 OS::SNPrint(chars, len + 1, "s%d", stack_slot_index_); 56 OS::SNPrint(chars, len + 1, "s%d", stack_slot_index_);
31 return chars; 57 return chars;
32 } 58 }
33 59
60 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
61 intptr_t from_index =
62 deopt_context->from_frame_size() - stack_slot_index_ - 1;
63 intptr_t* from_addr = deopt_context->GetFromFrameAddressAt(from_index);
64 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
65 *to_addr = *from_addr;
66 }
67
34 private: 68 private:
35 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. 69 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
36 70
37 DISALLOW_COPY_AND_ASSIGN(DeoptStackSlotInstr); 71 DISALLOW_COPY_AND_ASSIGN(DeoptStackSlotInstr);
38 }; 72 };
39 73
40 74
41 // Deoptimization instruction creating return address using function and 75 // Deoptimization instruction creating return address using function and
42 // deopt-id stored at 'object_table_index'. 76 // deopt-id stored at 'object_table_index'.
43 class DeoptRetAddrInstr : public DeoptInstr { 77 class DeoptRetAddrInstr : public DeoptInstr {
44 public: 78 public:
45 explicit DeoptRetAddrInstr(intptr_t object_table_index) 79 explicit DeoptRetAddrInstr(intptr_t object_table_index)
46 : object_table_index_(object_table_index) { 80 : object_table_index_(object_table_index) {
47 ASSERT(object_table_index >= 0); 81 ASSERT(object_table_index >= 0);
48 } 82 }
49 83
50 virtual intptr_t from_index() const { return object_table_index_; } 84 virtual intptr_t from_index() const { return object_table_index_; }
51 virtual DeoptInstr::Kind kind() const { return kSetRetAddress; } 85 virtual DeoptInstr::Kind kind() const { return kSetRetAddress; }
52 86
53 virtual const char* ToCString() const { 87 virtual const char* ToCString() const {
54 intptr_t len = OS::SNPrint(NULL, 0, "ret oti:%d", object_table_index_); 88 intptr_t len = OS::SNPrint(NULL, 0, "ret oti:%d", object_table_index_);
55 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 89 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
56 OS::SNPrint(chars, len + 1, "ret oti:%d", object_table_index_); 90 OS::SNPrint(chars, len + 1, "ret oti:%d", object_table_index_);
57 return chars; 91 return chars;
58 } 92 }
59 93
94 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
95 Function& function = Function::Handle();
96 function ^= deopt_context->ObjectAt(object_table_index_);
97 Smi& deopt_id_as_smi = Smi::Handle();
98 deopt_id_as_smi ^= deopt_context->ObjectAt(object_table_index_ + 1);
99 const Code& code = Code::Handle(function.unoptimized_code());
100 uword continue_at_pc = code.GetDeoptPcAtDeoptId(deopt_id_as_smi.Value());
101 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
102 *to_addr = continue_at_pc;
103 }
104
60 private: 105 private:
61 const intptr_t object_table_index_; 106 const intptr_t object_table_index_;
62 107
63 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrInstr); 108 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrInstr);
64 }; 109 };
65 110
66 111
67 // Deoptimization instruction moving a constant stored at 'object_table_index'. 112 // Deoptimization instruction moving a constant stored at 'object_table_index'.
68 class DeoptConstantInstr : public DeoptInstr { 113 class DeoptConstantInstr : public DeoptInstr {
69 public: 114 public:
70 explicit DeoptConstantInstr(intptr_t object_table_index) 115 explicit DeoptConstantInstr(intptr_t object_table_index)
71 : object_table_index_(object_table_index) { 116 : object_table_index_(object_table_index) {
72 ASSERT(object_table_index >= 0); 117 ASSERT(object_table_index >= 0);
73 } 118 }
74 119
75 virtual intptr_t from_index() const { return object_table_index_; } 120 virtual intptr_t from_index() const { return object_table_index_; }
76 virtual DeoptInstr::Kind kind() const { return kCopyConstant; } 121 virtual DeoptInstr::Kind kind() const { return kCopyConstant; }
77 122
78 virtual const char* ToCString() const { 123 virtual const char* ToCString() const {
79 intptr_t len = OS::SNPrint(NULL, 0, "const oti:%d", object_table_index_); 124 intptr_t len = OS::SNPrint(NULL, 0, "const oti:%d", object_table_index_);
80 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 125 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
81 OS::SNPrint(chars, len + 1, "const oti:%d", object_table_index_); 126 OS::SNPrint(chars, len + 1, "const oti:%d", object_table_index_);
82 return chars; 127 return chars;
83 } 128 }
84 129
130 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
131 const Object& obj = Object::Handle(
132 deopt_context->ObjectAt(object_table_index_));
siva 2012/08/09 21:38:19 There will be many ConstInstr instructions so it m
srdjan 2012/08/09 23:28:30 Discussed off-line, caching isolate instead.
133 RawObject** to_addr = reinterpret_cast<RawObject**>(
134 deopt_context->GetToFrameAddressAt(to_index));
135 *to_addr = obj.raw();
136 }
137
85 private: 138 private:
86 const intptr_t object_table_index_; 139 const intptr_t object_table_index_;
87 140
88 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); 141 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr);
89 }; 142 };
90 143
91 144
92 // Deoptimization instruction moving a register. 145 // Deoptimization instruction moving a register.
93 class DeoptRegisterInstr: public DeoptInstr { 146 class DeoptRegisterInstr: public DeoptInstr {
94 public: 147 public:
95 explicit DeoptRegisterInstr(intptr_t reg_as_int) 148 explicit DeoptRegisterInstr(intptr_t reg_as_int)
96 : reg_(static_cast<Register>(reg_as_int)) {} 149 : reg_(static_cast<Register>(reg_as_int)) {}
97 150
98 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } 151 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
99 virtual DeoptInstr::Kind kind() const { return kCopyRegister; } 152 virtual DeoptInstr::Kind kind() const { return kCopyRegister; }
100 153
101 virtual const char* ToCString() const { 154 virtual const char* ToCString() const {
102 return Assembler::RegisterName(reg_); 155 return Assembler::RegisterName(reg_);
103 } 156 }
104 157
158 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
159 intptr_t value = deopt_context->RegisterValue(reg_);
160 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
161 *to_addr = value;
162 }
163
105 private: 164 private:
106 const Register reg_; 165 const Register reg_;
107 166
108 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); 167 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr);
109 }; 168 };
110 169
111 170
112 // Deoptimization instruction creating a PC marker for the code of 171 // Deoptimization instruction creating a PC marker for the code of
113 // function at 'object_table_index'. 172 // function at 'object_table_index'.
114 class DeoptPcMarkerInstr : public DeoptInstr { 173 class DeoptPcMarkerInstr : public DeoptInstr {
115 public: 174 public:
116 explicit DeoptPcMarkerInstr(intptr_t object_table_index) 175 explicit DeoptPcMarkerInstr(intptr_t object_table_index)
117 : object_table_index_(object_table_index) { 176 : object_table_index_(object_table_index) {
118 ASSERT(object_table_index >= 0); 177 ASSERT(object_table_index >= 0);
119 } 178 }
120 179
121 virtual intptr_t from_index() const { return object_table_index_; } 180 virtual intptr_t from_index() const { return object_table_index_; }
122 virtual DeoptInstr::Kind kind() const { return kSetPcMarker; } 181 virtual DeoptInstr::Kind kind() const { return kSetPcMarker; }
123 182
124 virtual const char* ToCString() const { 183 virtual const char* ToCString() const {
125 intptr_t len = OS::SNPrint(NULL, 0, "pcmark oti:%d", object_table_index_); 184 intptr_t len = OS::SNPrint(NULL, 0, "pcmark oti:%d", object_table_index_);
126 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 185 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
127 OS::SNPrint(chars, len + 1, "pcmark oti:%d", object_table_index_); 186 OS::SNPrint(chars, len + 1, "pcmark oti:%d", object_table_index_);
128 return chars; 187 return chars;
129 } 188 }
130 189
190 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
191 Function& function = Function::Handle();
192 function ^= deopt_context->ObjectAt(object_table_index_);
193 const Code& code = Code::Handle(function.unoptimized_code());
194 intptr_t pc_marker = code.EntryPoint() +
195 AssemblerMacros::kOffsetOfSavedPCfromEntrypoint;
196 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
197 *to_addr = pc_marker;
198 }
199
131 private: 200 private:
132 intptr_t object_table_index_; 201 intptr_t object_table_index_;
133 202
134 DISALLOW_COPY_AND_ASSIGN(DeoptPcMarkerInstr); 203 DISALLOW_COPY_AND_ASSIGN(DeoptPcMarkerInstr);
135 }; 204 };
136 205
137 206
138 // Deoptimization instruction copying the caller saved FP from optimized frame. 207 // Deoptimization instruction copying the caller saved FP from optimized frame.
139 class DeoptCallerFpInstr : public DeoptInstr { 208 class DeoptCallerFpInstr : public DeoptInstr {
140 public: 209 public:
141 DeoptCallerFpInstr() {} 210 DeoptCallerFpInstr() {}
142 211
143 virtual intptr_t from_index() const { return 0; } 212 virtual intptr_t from_index() const { return 0; }
144 virtual DeoptInstr::Kind kind() const { return kSetCallerFp; } 213 virtual DeoptInstr::Kind kind() const { return kSetCallerFp; }
145 214
146 virtual const char* ToCString() const { return "callerfp"; } 215 virtual const char* ToCString() const {
216 return "callerfp";
217 }
218
219 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
220 intptr_t* from_addr = deopt_context->GetFromFpAddress();
221 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
222 *to_addr = *from_addr;
223 }
147 224
148 private: 225 private:
149 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); 226 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr);
150 }; 227 };
151 228
152 229
153 // Deoptimization instruction copying the caller return address from optimzied 230 // Deoptimization instruction copying the caller return address from optimized
154 // frame. 231 // frame.
155 class DeoptCallerPcInstr : public DeoptInstr { 232 class DeoptCallerPcInstr : public DeoptInstr {
156 public: 233 public:
157 DeoptCallerPcInstr() {} 234 DeoptCallerPcInstr() {}
158 235
159 virtual intptr_t from_index() const { return 0; } 236 virtual intptr_t from_index() const { return 0; }
160 virtual DeoptInstr::Kind kind() const { return kSetCallerPc; } 237 virtual DeoptInstr::Kind kind() const { return kSetCallerPc; }
161 238
162 virtual const char* ToCString() const { return "callerpc"; } 239 virtual const char* ToCString() const {
240 return "callerpc";
241 }
242
243 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
244 intptr_t* from_addr = deopt_context->GetFromPcAddress();
245 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
246 *to_addr = *from_addr;
247 }
163 248
164 private: 249 private:
165 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); 250 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr);
166 }; 251 };
167 252
168 253
169 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { 254 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) {
170 Kind kind = static_cast<Kind>(kind_as_int); 255 Kind kind = static_cast<Kind>(kind_as_int);
171 switch (kind) { 256 switch (kind) {
172 case kCopyStackSlot: return new DeoptStackSlotInstr(from_index); 257 case kCopyStackSlot: return new DeoptStackSlotInstr(from_index);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 void DeoptInfoBuilder::AddCopy(const Location& from_loc, 304 void DeoptInfoBuilder::AddCopy(const Location& from_loc,
220 const Value& from_value, 305 const Value& from_value,
221 const intptr_t to_index) { 306 const intptr_t to_index) {
222 DeoptInstr* deopt_instr = NULL; 307 DeoptInstr* deopt_instr = NULL;
223 if (from_loc.IsConstant()) { 308 if (from_loc.IsConstant()) {
224 intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant()); 309 intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant());
225 deopt_instr = new DeoptConstantInstr(object_table_index); 310 deopt_instr = new DeoptConstantInstr(object_table_index);
226 } else if (from_loc.IsRegister()) { 311 } else if (from_loc.IsRegister()) {
227 deopt_instr = new DeoptRegisterInstr(from_loc.reg()); 312 deopt_instr = new DeoptRegisterInstr(from_loc.reg());
228 } else if (from_loc.IsStackSlot()) { 313 } else if (from_loc.IsStackSlot()) {
229 deopt_instr = new DeoptStackSlotInstr(from_loc.stack_index() + num_args_); 314 intptr_t from_index = (from_loc.stack_index() < 0) ?
315 from_loc.stack_index() + num_args_ :
316 from_loc.stack_index() + num_args_ -
317 ParsedFunction::kFirstLocalSlotIndex + 1;
318 deopt_instr = new DeoptStackSlotInstr(from_index);
230 } else if (from_loc.IsInvalid()) { 319 } else if (from_loc.IsInvalid()) {
231 ASSERT(from_value.IsConstant()); 320 ASSERT(from_value.IsConstant());
232 const Object& obj = from_value.AsConstant()->value(); 321 const Object& obj = from_value.AsConstant()->value();
233 intptr_t object_table_index = FindOrAddObjectInTable(obj); 322 intptr_t object_table_index = FindOrAddObjectInTable(obj);
234 deopt_instr = new DeoptConstantInstr(object_table_index); 323 deopt_instr = new DeoptConstantInstr(object_table_index);
235 } else { 324 } else {
236 UNREACHABLE(); 325 UNREACHABLE();
237 } 326 }
238 ASSERT(to_index == instructions_.length()); 327 ASSERT(to_index == instructions_.length());
239 instructions_.Add(deopt_instr); 328 instructions_.Add(deopt_instr);
(...skipping 16 matching lines...) Expand all
256 const intptr_t len = instructions_.length(); 345 const intptr_t len = instructions_.length();
257 const DeoptInfo& deopt_info = DeoptInfo::Handle(DeoptInfo::New(len)); 346 const DeoptInfo& deopt_info = DeoptInfo::Handle(DeoptInfo::New(len));
258 for (intptr_t i = 0; i < len; i++) { 347 for (intptr_t i = 0; i < len; i++) {
259 DeoptInstr* instr = instructions_[i]; 348 DeoptInstr* instr = instructions_[i];
260 deopt_info.SetAt(i, instr->kind(), instr->from_index()); 349 deopt_info.SetAt(i, instr->kind(), instr->from_index());
261 } 350 }
262 return deopt_info.raw(); 351 return deopt_info.raw();
263 } 352 }
264 353
265 } // namespace dart 354 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698