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

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

Issue 10913031: Split deopt-after and deopt-before handling: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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/deopt_instructions.h" 5 #include "vm/deopt_instructions.h"
6 6
7 #include "vm/assembler_macros.h" 7 #include "vm/assembler_macros.h"
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 #include "vm/locations.h" 9 #include "vm/locations.h"
10 #include "vm/parser.h" 10 #include "vm/parser.h"
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 } 105 }
106 106
107 private: 107 private:
108 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. 108 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
109 109
110 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr); 110 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr);
111 }; 111 };
112 112
113 113
114 // Deoptimization instruction creating return address using function and 114 // Deoptimization instruction creating return address using function and
115 // deopt-id stored at 'object_table_index'. 115 // deopt-id stored at 'object_table_index'. Uses the deopt-after
116 class DeoptRetAddrInstr : public DeoptInstr { 116 // continuation point.
117 class DeoptRetAddrAfterInstr : public DeoptInstr {
117 public: 118 public:
118 explicit DeoptRetAddrInstr(intptr_t object_table_index) 119 explicit DeoptRetAddrAfterInstr(intptr_t object_table_index)
119 : object_table_index_(object_table_index) { 120 : object_table_index_(object_table_index) {
120 ASSERT(object_table_index >= 0); 121 ASSERT(object_table_index >= 0);
121 } 122 }
122 123
123 virtual intptr_t from_index() const { return object_table_index_; } 124 virtual intptr_t from_index() const { return object_table_index_; }
124 virtual DeoptInstr::Kind kind() const { return kSetRetAddress; } 125 virtual DeoptInstr::Kind kind() const { return kSetRetAfterAddress; }
125 126
126 virtual const char* ToCString() const { 127 virtual const char* ToCString() const {
127 intptr_t len = OS::SNPrint(NULL, 0, "ret oti:%d", object_table_index_); 128 intptr_t len = OS::SNPrint(NULL, 0, "ret aft oti:%d", object_table_index_);
128 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 129 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
129 OS::SNPrint(chars, len + 1, "ret oti:%d", object_table_index_); 130 OS::SNPrint(chars, len + 1, "ret aft oti:%d", object_table_index_);
130 return chars; 131 return chars;
131 } 132 }
132 133
133 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { 134 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
134 Function& function = Function::Handle(deopt_context->isolate()); 135 Function& function = Function::Handle(deopt_context->isolate());
135 function ^= deopt_context->ObjectAt(object_table_index_); 136 function ^= deopt_context->ObjectAt(object_table_index_);
136 Smi& deopt_id_as_smi = Smi::Handle(deopt_context->isolate()); 137 Smi& deopt_id_as_smi = Smi::Handle(deopt_context->isolate());
137 deopt_id_as_smi ^= deopt_context->ObjectAt(object_table_index_ + 1); 138 deopt_id_as_smi ^= deopt_context->ObjectAt(object_table_index_ + 1);
138 const Code& code = 139 const Code& code =
139 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); 140 Code::Handle(deopt_context->isolate(), function.unoptimized_code());
140 uword continue_at_pc = 141 uword continue_at_pc =
142 code.GetDeoptAfterPcAtDeoptId(deopt_id_as_smi.Value());
143 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
144 *to_addr = continue_at_pc;
145 }
146
147 private:
148 const intptr_t object_table_index_;
149
150 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrAfterInstr);
151 };
152
153
154 // Deoptimization instruction creating return address using function and
155 // deopt-id stored at 'object_table_index'. Uses the deopt-before
156 // continuation point.
157 class DeoptRetAddrBeforeInstr : public DeoptInstr {
158 public:
159 explicit DeoptRetAddrBeforeInstr(intptr_t object_table_index)
160 : object_table_index_(object_table_index) {
161 ASSERT(object_table_index >= 0);
162 }
163
164 virtual intptr_t from_index() const { return object_table_index_; }
165 virtual DeoptInstr::Kind kind() const { return kSetRetBeforeAddress; }
166
167 virtual const char* ToCString() const {
168 intptr_t len = OS::SNPrint(NULL, 0, "ret bef oti:%d", object_table_index_);
169 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
170 OS::SNPrint(chars, len + 1, "ret bef oti:%d", object_table_index_);
171 return chars;
172 }
173
174 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
175 Function& function = Function::Handle(deopt_context->isolate());
176 function ^= deopt_context->ObjectAt(object_table_index_);
177 Smi& deopt_id_as_smi = Smi::Handle(deopt_context->isolate());
178 deopt_id_as_smi ^= deopt_context->ObjectAt(object_table_index_ + 1);
179 const Code& code =
180 Code::Handle(deopt_context->isolate(), function.unoptimized_code());
181 uword continue_at_pc =
141 code.GetDeoptBeforePcAtDeoptId(deopt_id_as_smi.Value()); 182 code.GetDeoptBeforePcAtDeoptId(deopt_id_as_smi.Value());
142 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); 183 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
143 *to_addr = continue_at_pc; 184 *to_addr = continue_at_pc;
144 } 185 }
145 186
146 private: 187 private:
147 const intptr_t object_table_index_; 188 const intptr_t object_table_index_;
148 189
149 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrInstr); 190 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrBeforeInstr);
150 }; 191 };
151 192
152 193
153 // Deoptimization instruction moving a constant stored at 'object_table_index'. 194 // Deoptimization instruction moving a constant stored at 'object_table_index'.
154 class DeoptConstantInstr : public DeoptInstr { 195 class DeoptConstantInstr : public DeoptInstr {
155 public: 196 public:
156 explicit DeoptConstantInstr(intptr_t object_table_index) 197 explicit DeoptConstantInstr(intptr_t object_table_index)
157 : object_table_index_(object_table_index) { 198 : object_table_index_(object_table_index) {
158 ASSERT(object_table_index >= 0); 199 ASSERT(object_table_index >= 0);
159 } 200 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 private: 360 private:
320 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); 361 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr);
321 }; 362 };
322 363
323 364
324 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { 365 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) {
325 Kind kind = static_cast<Kind>(kind_as_int); 366 Kind kind = static_cast<Kind>(kind_as_int);
326 switch (kind) { 367 switch (kind) {
327 case kCopyStackSlot: return new DeoptStackSlotInstr(from_index); 368 case kCopyStackSlot: return new DeoptStackSlotInstr(from_index);
328 case kCopyDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); 369 case kCopyDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index);
329 case kSetRetAddress: return new DeoptRetAddrInstr(from_index); 370 case kSetRetAfterAddress: return new DeoptRetAddrAfterInstr(from_index);
371 case kSetRetBeforeAddress: return new DeoptRetAddrBeforeInstr(from_index);
330 case kCopyConstant: return new DeoptConstantInstr(from_index); 372 case kCopyConstant: return new DeoptConstantInstr(from_index);
331 case kCopyRegister: return new DeoptRegisterInstr(from_index); 373 case kCopyRegister: return new DeoptRegisterInstr(from_index);
332 case kCopyXmmRegister: return new DeoptXmmRegisterInstr(from_index); 374 case kCopyXmmRegister: return new DeoptXmmRegisterInstr(from_index);
333 case kSetPcMarker: return new DeoptPcMarkerInstr(from_index); 375 case kSetPcMarker: return new DeoptPcMarkerInstr(from_index);
334 case kSetCallerFp: return new DeoptCallerFpInstr(); 376 case kSetCallerFp: return new DeoptCallerFpInstr();
335 case kSetCallerPc: return new DeoptCallerPcInstr(); 377 case kSetCallerPc: return new DeoptCallerPcInstr();
336 } 378 }
337 UNREACHABLE(); 379 UNREACHABLE();
338 return NULL; 380 return NULL;
339 } 381 }
340 382
341 383
342 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const { 384 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const {
343 for (intptr_t i = 0; i < object_table_.Length(); i++) { 385 for (intptr_t i = 0; i < object_table_.Length(); i++) {
344 if (object_table_.At(i) == obj.raw()) { 386 if (object_table_.At(i) == obj.raw()) {
345 return i; 387 return i;
346 } 388 }
347 } 389 }
348 // Add object. 390 // Add object.
349 const intptr_t result = object_table_.Length(); 391 const intptr_t result = object_table_.Length();
350 object_table_.Add(obj); 392 object_table_.Add(obj);
351 return result; 393 return result;
352 } 394 }
353 395
354 396
355 // Will be neeeded for inlined functions, currently trivial. 397 void DeoptInfoBuilder::AddReturnAddressBefore(const Function& function,
356 void DeoptInfoBuilder::AddReturnAddress(const Function& function, 398 intptr_t deopt_id,
357 intptr_t deopt_id, 399 intptr_t to_index) {
358 intptr_t to_index) {
359 const intptr_t object_table_index = object_table_.Length(); 400 const intptr_t object_table_index = object_table_.Length();
360 object_table_.Add(function); 401 object_table_.Add(function);
361 object_table_.Add(Smi::ZoneHandle(Smi::New(deopt_id))); 402 object_table_.Add(Smi::ZoneHandle(Smi::New(deopt_id)));
362 ASSERT(to_index == instructions_.length()); 403 ASSERT(to_index == instructions_.length());
363 instructions_.Add(new DeoptRetAddrInstr(object_table_index)); 404 instructions_.Add(new DeoptRetAddrBeforeInstr(object_table_index));
405 }
406
407
408 void DeoptInfoBuilder::AddReturnAddressAfter(const Function& function,
409 intptr_t deopt_id,
410 intptr_t to_index) {
411 const intptr_t object_table_index = object_table_.Length();
412 object_table_.Add(function);
413 object_table_.Add(Smi::ZoneHandle(Smi::New(deopt_id)));
414 ASSERT(to_index == instructions_.length());
415 instructions_.Add(new DeoptRetAddrAfterInstr(object_table_index));
364 } 416 }
365 417
366 418
367 void DeoptInfoBuilder::AddPcMarker(const Function& function, 419 void DeoptInfoBuilder::AddPcMarker(const Function& function,
368 intptr_t to_index) { 420 intptr_t to_index) {
369 // Function object was already added by AddReturnAddress, find it. 421 // Function object was already added by AddReturnAddress, find it.
370 intptr_t from_index = FindOrAddObjectInTable(function); 422 intptr_t from_index = FindOrAddObjectInTable(function);
371 ASSERT(to_index == instructions_.length()); 423 ASSERT(to_index == instructions_.length());
372 instructions_.Add(new DeoptPcMarkerInstr(from_index)); 424 instructions_.Add(new DeoptPcMarkerInstr(from_index));
373 } 425 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 const intptr_t len = instructions_.length(); 472 const intptr_t len = instructions_.length();
421 const DeoptInfo& deopt_info = DeoptInfo::Handle(DeoptInfo::New(len)); 473 const DeoptInfo& deopt_info = DeoptInfo::Handle(DeoptInfo::New(len));
422 for (intptr_t i = 0; i < len; i++) { 474 for (intptr_t i = 0; i < len; i++) {
423 DeoptInstr* instr = instructions_[i]; 475 DeoptInstr* instr = instructions_[i];
424 deopt_info.SetAt(i, instr->kind(), instr->from_index()); 476 deopt_info.SetAt(i, instr->kind(), instr->from_index());
425 } 477 }
426 return deopt_info.raw(); 478 return deopt_info.raw();
427 } 479 }
428 480
429 } // namespace dart 481 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698