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

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

Issue 11014020: Pack deopt ID into the return before and return after deopt instructions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 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
« no previous file with comments | « no previous file | runtime/vm/object.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/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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. 119 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
120 120
121 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr); 121 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr);
122 }; 122 };
123 123
124 124
125 // Deoptimization instruction creating return address using function and 125 // Deoptimization instruction creating return address using function and
126 // deopt-id stored at 'object_table_index'. Uses the deopt-after 126 // deopt-id stored at 'object_table_index'. Uses the deopt-after
127 // continuation point. 127 // continuation point.
128 class DeoptRetAddrAfterInstr : public DeoptInstr { 128 class DeoptRetAddrAfterInstr : public DeoptInstr {
129 private:
130 static const intptr_t kFieldWidth = kBitsPerWord / 2;
131
129 public: 132 public:
130 explicit DeoptRetAddrAfterInstr(intptr_t object_table_index) 133 class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { };
131 : object_table_index_(object_table_index) { 134 class DeoptId : public BitField<intptr_t, kFieldWidth, kFieldWidth> { };
135
136 DeoptRetAddrAfterInstr(intptr_t object_table_index, intptr_t deopt_id)
137 : object_table_index_(object_table_index), deopt_id_(deopt_id) {
132 ASSERT(object_table_index >= 0); 138 ASSERT(object_table_index >= 0);
139 ASSERT(deopt_id >= 0);
133 } 140 }
srdjan 2012/10/02 17:34:49 How about overloading constructor with: DeoptRetAd
Kevin Millikin (Google) 2012/10/03 07:05:36 OK.
134 141
135 virtual intptr_t from_index() const { return object_table_index_; } 142 virtual intptr_t from_index() const {
143 return ObjectTableIndex::encode(object_table_index_) |
144 DeoptId::encode(deopt_id_);
145 }
136 virtual DeoptInstr::Kind kind() const { return kSetRetAfterAddress; } 146 virtual DeoptInstr::Kind kind() const { return kSetRetAfterAddress; }
137 147
138 virtual const char* ToCString() const { 148 virtual const char* ToCString() const {
139 const char* format = "ret aft oti:%"Pd""; 149 const char* format = "ret aft oti:%"Pd"(%"Pd")";
140 intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_); 150 intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_, deopt_id_);
141 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 151 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
142 OS::SNPrint(chars, len + 1, format, object_table_index_); 152 OS::SNPrint(chars, len + 1, format, object_table_index_, deopt_id_);
143 return chars; 153 return chars;
144 } 154 }
145 155
146 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { 156 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
147 Function& function = Function::Handle(deopt_context->isolate()); 157 Function& function = Function::Handle(deopt_context->isolate());
148 function ^= deopt_context->ObjectAt(object_table_index_); 158 function ^= deopt_context->ObjectAt(object_table_index_);
149 Smi& deopt_id_as_smi = Smi::Handle(deopt_context->isolate());
150 deopt_id_as_smi ^= deopt_context->ObjectAt(object_table_index_ + 1);
151 const Code& code = 159 const Code& code =
152 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); 160 Code::Handle(deopt_context->isolate(), function.unoptimized_code());
153 uword continue_at_pc = 161 uword continue_at_pc = code.GetDeoptAfterPcAtDeoptId(deopt_id_);
154 code.GetDeoptAfterPcAtDeoptId(deopt_id_as_smi.Value());
155 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); 162 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
156 *to_addr = continue_at_pc; 163 *to_addr = continue_at_pc;
157 } 164 }
158 165
159 private: 166 private:
160 const intptr_t object_table_index_; 167 const intptr_t object_table_index_;
168 const intptr_t deopt_id_;
161 169
162 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrAfterInstr); 170 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrAfterInstr);
163 }; 171 };
164 172
165 173
166 // Deoptimization instruction creating return address using function and 174 // Deoptimization instruction creating return address using function and
167 // deopt-id stored at 'object_table_index'. Uses the deopt-before 175 // deopt-id stored at 'object_table_index'. Uses the deopt-before
168 // continuation point. 176 // continuation point.
169 class DeoptRetAddrBeforeInstr : public DeoptInstr { 177 class DeoptRetAddrBeforeInstr : public DeoptInstr {
178 private:
179 static const intptr_t kFieldWidth = kBitsPerWord / 2;
180
170 public: 181 public:
171 explicit DeoptRetAddrBeforeInstr(intptr_t object_table_index) 182 class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { };
172 : object_table_index_(object_table_index) { 183 class DeoptId : public BitField<intptr_t, kFieldWidth, kFieldWidth> { };
184
185 DeoptRetAddrBeforeInstr(intptr_t object_table_index, intptr_t deopt_id)
186 : object_table_index_(object_table_index), deopt_id_(deopt_id) {
srdjan 2012/10/02 17:34:49 ditto.
173 ASSERT(object_table_index >= 0); 187 ASSERT(object_table_index >= 0);
188 ASSERT(deopt_id_ >= 0);
174 } 189 }
175 190
176 virtual intptr_t from_index() const { return object_table_index_; } 191 virtual intptr_t from_index() const {
192 return ObjectTableIndex::encode(object_table_index_) |
193 DeoptId::encode(deopt_id_);
194 }
177 virtual DeoptInstr::Kind kind() const { return kSetRetBeforeAddress; } 195 virtual DeoptInstr::Kind kind() const { return kSetRetBeforeAddress; }
178 196
179 virtual const char* ToCString() const { 197 virtual const char* ToCString() const {
180 const char* format = "ret bef oti:%"Pd""; 198 const char* format = "ret bef oti:%"Pd"(%"Pd")";
181 intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_); 199 intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_, deopt_id_);
182 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 200 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
183 OS::SNPrint(chars, len + 1, format, object_table_index_); 201 OS::SNPrint(chars, len + 1, format, object_table_index_, deopt_id_);
184 return chars; 202 return chars;
185 } 203 }
186 204
187 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { 205 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
188 Function& function = Function::Handle(deopt_context->isolate()); 206 Function& function = Function::Handle(deopt_context->isolate());
189 function ^= deopt_context->ObjectAt(object_table_index_); 207 function ^= deopt_context->ObjectAt(object_table_index_);
190 Smi& deopt_id_as_smi = Smi::Handle(deopt_context->isolate());
191 deopt_id_as_smi ^= deopt_context->ObjectAt(object_table_index_ + 1);
192 const Code& code = 208 const Code& code =
193 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); 209 Code::Handle(deopt_context->isolate(), function.unoptimized_code());
194 uword continue_at_pc = 210 uword continue_at_pc = code.GetDeoptBeforePcAtDeoptId(deopt_id_);
195 code.GetDeoptBeforePcAtDeoptId(deopt_id_as_smi.Value());
196 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); 211 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
197 *to_addr = continue_at_pc; 212 *to_addr = continue_at_pc;
198 } 213 }
199 214
200 private: 215 private:
201 const intptr_t object_table_index_; 216 const intptr_t object_table_index_;
217 const intptr_t deopt_id_;
202 218
203 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrBeforeInstr); 219 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrBeforeInstr);
204 }; 220 };
205 221
206 222
207 // Deoptimization instruction moving a constant stored at 'object_table_index'. 223 // Deoptimization instruction moving a constant stored at 'object_table_index'.
208 class DeoptConstantInstr : public DeoptInstr { 224 class DeoptConstantInstr : public DeoptInstr {
209 public: 225 public:
210 explicit DeoptConstantInstr(intptr_t object_table_index) 226 explicit DeoptConstantInstr(intptr_t object_table_index)
211 : object_table_index_(object_table_index) { 227 : object_table_index_(object_table_index) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 private: 392 private:
377 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); 393 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr);
378 }; 394 };
379 395
380 396
381 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { 397 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) {
382 Kind kind = static_cast<Kind>(kind_as_int); 398 Kind kind = static_cast<Kind>(kind_as_int);
383 switch (kind) { 399 switch (kind) {
384 case kCopyStackSlot: return new DeoptStackSlotInstr(from_index); 400 case kCopyStackSlot: return new DeoptStackSlotInstr(from_index);
385 case kCopyDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); 401 case kCopyDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index);
386 case kSetRetAfterAddress: return new DeoptRetAddrAfterInstr(from_index); 402 case kSetRetAfterAddress:
387 case kSetRetBeforeAddress: return new DeoptRetAddrBeforeInstr(from_index); 403 return new DeoptRetAddrAfterInstr(
404 DeoptRetAddrAfterInstr::ObjectTableIndex::decode(from_index),
405 DeoptRetAddrAfterInstr::DeoptId::decode(from_index));
406 case kSetRetBeforeAddress:
407 return new DeoptRetAddrBeforeInstr(
408 DeoptRetAddrBeforeInstr::ObjectTableIndex::decode(from_index),
409 DeoptRetAddrBeforeInstr::DeoptId::decode(from_index));
388 case kCopyConstant: return new DeoptConstantInstr(from_index); 410 case kCopyConstant: return new DeoptConstantInstr(from_index);
389 case kCopyRegister: return new DeoptRegisterInstr(from_index); 411 case kCopyRegister: return new DeoptRegisterInstr(from_index);
390 case kCopyXmmRegister: return new DeoptXmmRegisterInstr(from_index); 412 case kCopyXmmRegister: return new DeoptXmmRegisterInstr(from_index);
391 case kSetPcMarker: return new DeoptPcMarkerInstr(from_index); 413 case kSetPcMarker: return new DeoptPcMarkerInstr(from_index);
392 case kSetCallerFp: return new DeoptCallerFpInstr(); 414 case kSetCallerFp: return new DeoptCallerFpInstr();
393 case kSetCallerPc: return new DeoptCallerPcInstr(); 415 case kSetCallerPc: return new DeoptCallerPcInstr();
394 } 416 }
395 UNREACHABLE(); 417 UNREACHABLE();
396 return NULL; 418 return NULL;
397 } 419 }
398 420
399 421
400 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const { 422 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const {
401 for (intptr_t i = 0; i < object_table_.Length(); i++) { 423 for (intptr_t i = 0; i < object_table_.Length(); i++) {
402 if (object_table_.At(i) == obj.raw()) { 424 if (object_table_.At(i) == obj.raw()) {
403 return i; 425 return i;
404 } 426 }
405 } 427 }
406 // Add object. 428 // Add object.
407 const intptr_t result = object_table_.Length(); 429 const intptr_t result = object_table_.Length();
408 object_table_.Add(obj); 430 object_table_.Add(obj);
409 return result; 431 return result;
410 } 432 }
411 433
412 434
413 void DeoptInfoBuilder::AddReturnAddressBefore(const Function& function, 435 void DeoptInfoBuilder::AddReturnAddressBefore(const Function& function,
414 intptr_t deopt_id, 436 intptr_t deopt_id,
415 intptr_t to_index) { 437 intptr_t to_index) {
416 const intptr_t object_table_index = object_table_.Length(); 438 const intptr_t object_table_index = FindOrAddObjectInTable(function);
417 object_table_.Add(function);
418 object_table_.Add(Smi::ZoneHandle(Smi::New(deopt_id)));
419 ASSERT(to_index == instructions_.length()); 439 ASSERT(to_index == instructions_.length());
420 instructions_.Add(new DeoptRetAddrBeforeInstr(object_table_index)); 440 instructions_.Add(new DeoptRetAddrBeforeInstr(object_table_index, deopt_id));
421 } 441 }
422 442
423 443
424 void DeoptInfoBuilder::AddReturnAddressAfter(const Function& function, 444 void DeoptInfoBuilder::AddReturnAddressAfter(const Function& function,
425 intptr_t deopt_id, 445 intptr_t deopt_id,
426 intptr_t to_index) { 446 intptr_t to_index) {
427 const intptr_t object_table_index = object_table_.Length(); 447 const intptr_t object_table_index = FindOrAddObjectInTable(function);
428 object_table_.Add(function);
429 object_table_.Add(Smi::ZoneHandle(Smi::New(deopt_id)));
430 ASSERT(to_index == instructions_.length()); 448 ASSERT(to_index == instructions_.length());
431 instructions_.Add(new DeoptRetAddrAfterInstr(object_table_index)); 449 instructions_.Add(new DeoptRetAddrAfterInstr(object_table_index, deopt_id));
432 } 450 }
433 451
434 452
435 void DeoptInfoBuilder::AddPcMarker(const Function& function, 453 void DeoptInfoBuilder::AddPcMarker(const Function& function,
436 intptr_t to_index) { 454 intptr_t to_index) {
437 // Function object was already added by AddReturnAddress, find it. 455 // Function object was already added by AddReturnAddress, find it.
438 intptr_t from_index = FindOrAddObjectInTable(function); 456 intptr_t from_index = FindOrAddObjectInTable(function);
439 ASSERT(to_index == instructions_.length()); 457 ASSERT(to_index == instructions_.length());
440 instructions_.Add(new DeoptPcMarkerInstr(from_index)); 458 instructions_.Add(new DeoptPcMarkerInstr(from_index));
441 } 459 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 Smi* offset, 541 Smi* offset,
524 DeoptInfo* info, 542 DeoptInfo* info,
525 Smi* reason) { 543 Smi* reason) {
526 intptr_t i = index * kEntrySize; 544 intptr_t i = index * kEntrySize;
527 *offset ^= table.At(i); 545 *offset ^= table.At(i);
528 *info ^= table.At(i + 1); 546 *info ^= table.At(i + 1);
529 *reason ^= table.At(i + 2); 547 *reason ^= table.At(i + 2);
530 } 548 }
531 549
532 } // namespace dart 550 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698