Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |