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

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

Powered by Google App Engine
This is Rietveld 408576698