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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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
« no previous file with comments | « runtime/vm/deopt_instructions.h ('k') | runtime/vm/disassembler.h » ('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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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.h" 7 #include "vm/assembler.h"
8 #include "vm/code_patcher.h" 8 #include "vm/code_patcher.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/disassembler.h" 10 #include "vm/disassembler.h"
11 #include "vm/intermediate_language.h" 11 #include "vm/intermediate_language.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/parser.h" 13 #include "vm/parser.h"
14 #include "vm/stack_frame.h" 14 #include "vm/stack_frame.h"
15 #include "vm/thread.h" 15 #include "vm/thread.h"
16 #include "vm/timeline.h" 16 #include "vm/timeline.h"
17 17
18 namespace dart { 18 namespace dart {
19 19
20 DEFINE_FLAG(bool, compress_deopt_info, true, 20 DEFINE_FLAG(bool,
21 compress_deopt_info,
22 true,
21 "Compress the size of the deoptimization info for optimized code."); 23 "Compress the size of the deoptimization info for optimized code.");
22 DECLARE_FLAG(bool, trace_deoptimization); 24 DECLARE_FLAG(bool, trace_deoptimization);
23 DECLARE_FLAG(bool, trace_deoptimization_verbose); 25 DECLARE_FLAG(bool, trace_deoptimization_verbose);
24 26
25 27
26 DeoptContext::DeoptContext(const StackFrame* frame, 28 DeoptContext::DeoptContext(const StackFrame* frame,
27 const Code& code, 29 const Code& code,
28 DestFrameOptions dest_options, 30 DestFrameOptions dest_options,
29 fpu_register_t* fpu_registers, 31 fpu_register_t* fpu_registers,
30 intptr_t* cpu_registers, 32 intptr_t* cpu_registers,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 ASSERT(!deopt_info.IsNull()); 65 ASSERT(!deopt_info.IsNull());
64 deopt_info_ = deopt_info.raw(); 66 deopt_info_ = deopt_info.raw();
65 67
66 const Function& function = Function::Handle(code.function()); 68 const Function& function = Function::Handle(code.function());
67 69
68 // Do not include incoming arguments if there are optional arguments 70 // Do not include incoming arguments if there are optional arguments
69 // (they are copied into local space at method entry). 71 // (they are copied into local space at method entry).
70 num_args_ = 72 num_args_ =
71 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); 73 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
72 74
73 // The fixed size section of the (fake) Dart frame called via a stub by the 75 // The fixed size section of the (fake) Dart frame called via a stub by the
74 // optimized function contains FP, PP (ARM and MIPS only), PC-marker and 76 // optimized function contains FP, PP (ARM and MIPS only), PC-marker and
75 // return-address. This section is copied as well, so that its contained 77 // return-address. This section is copied as well, so that its contained
76 // values can be updated before returning to the deoptimized function. 78 // values can be updated before returning to the deoptimized function.
77 // Note: on DBC stack grows upwards unlike on all other architectures. 79 // Note: on DBC stack grows upwards unlike on all other architectures.
78 #if defined(TARGET_ARCH_DBC) 80 #if defined(TARGET_ARCH_DBC)
79 ASSERT(frame->sp() >= frame->fp()); 81 ASSERT(frame->sp() >= frame->fp());
80 const intptr_t frame_size = (frame->sp() - frame->fp()) / kWordSize; 82 const intptr_t frame_size = (frame->sp() - frame->fp()) / kWordSize;
81 #else 83 #else
82 ASSERT(frame->fp() >= frame->sp()); 84 ASSERT(frame->fp() >= frame->sp());
83 const intptr_t frame_size = (frame->fp() - frame->sp()) / kWordSize; 85 const intptr_t frame_size = (frame->fp() - frame->sp()) / kWordSize;
84 #endif 86 #endif
85 87
86 source_frame_size_ = 88 source_frame_size_ = +kDartFrameFixedSize // For saved values below sp.
87 + kDartFrameFixedSize // For saved values below sp. 89 + frame_size // For frame size incl. sp.
88 + frame_size // For frame size incl. sp. 90 + 1 // For fp.
89 + 1 // For fp. 91 + kParamEndSlotFromFp // For saved values above fp.
90 + kParamEndSlotFromFp // For saved values above fp. 92 + num_args_; // For arguments.
91 + num_args_; // For arguments.
92 93
93 source_frame_ = FrameBase(frame); 94 source_frame_ = FrameBase(frame);
94 95
95 if (dest_options == kDestIsOriginalFrame) { 96 if (dest_options == kDestIsOriginalFrame) {
96 // Work from a copy of the source frame. 97 // Work from a copy of the source frame.
97 intptr_t* original_frame = source_frame_; 98 intptr_t* original_frame = source_frame_;
98 source_frame_ = new intptr_t[source_frame_size_]; 99 source_frame_ = new intptr_t[source_frame_size_];
99 ASSERT(source_frame_ != NULL); 100 ASSERT(source_frame_ != NULL);
100 for (intptr_t i = 0; i < source_frame_size_; i++) { 101 for (intptr_t i = 0; i < source_frame_size_; i++) {
101 source_frame_[i] = original_frame[i]; 102 source_frame_[i] = original_frame[i];
(...skipping 16 matching lines...) Expand all
118 if (dest_options != kDestIsAllocated) { 119 if (dest_options != kDestIsAllocated) {
119 // kDestIsAllocated is used by the debugger to generate a stack trace 120 // kDestIsAllocated is used by the debugger to generate a stack trace
120 // and does not signal a real deopt. 121 // and does not signal a real deopt.
121 deopt_start_micros_ = OS::GetCurrentMonotonicMicros(); 122 deopt_start_micros_ = OS::GetCurrentMonotonicMicros();
122 } 123 }
123 124
124 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { 125 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
125 THR_Print( 126 THR_Print(
126 "Deoptimizing (reason %d '%s') at " 127 "Deoptimizing (reason %d '%s') at "
127 "pc=%" Pp " fp=%" Pp " '%s' (count %d)\n", 128 "pc=%" Pp " fp=%" Pp " '%s' (count %d)\n",
128 deopt_reason(), 129 deopt_reason(), DeoptReasonToCString(deopt_reason()), frame->pc(),
129 DeoptReasonToCString(deopt_reason()), 130 frame->fp(), function.ToFullyQualifiedCString(),
130 frame->pc(),
131 frame->fp(),
132 function.ToFullyQualifiedCString(),
133 function.deoptimization_counter()); 131 function.deoptimization_counter());
134 } 132 }
135 } 133 }
136 134
137 135
138 DeoptContext::~DeoptContext() { 136 DeoptContext::~DeoptContext() {
139 // Delete memory for source frame and registers. 137 // Delete memory for source frame and registers.
140 if (source_frame_is_allocated_) { 138 if (source_frame_is_allocated_) {
141 delete[] source_frame_; 139 delete[] source_frame_;
142 } 140 }
(...skipping 22 matching lines...) Expand all
165 // Allocate all Dart objects needed before calling StartEvent, 163 // Allocate all Dart objects needed before calling StartEvent,
166 // which blocks safe points until Complete is called. 164 // which blocks safe points until Complete is called.
167 const Code& code = Code::Handle(zone(), code_); 165 const Code& code = Code::Handle(zone(), code_);
168 const Function& function = Function::Handle(zone(), code.function()); 166 const Function& function = Function::Handle(zone(), code.function());
169 const String& function_name = 167 const String& function_name =
170 String::Handle(zone(), function.QualifiedScrubbedName()); 168 String::Handle(zone(), function.QualifiedScrubbedName());
171 const char* reason = DeoptReasonToCString(deopt_reason()); 169 const char* reason = DeoptReasonToCString(deopt_reason());
172 const int counter = function.deoptimization_counter(); 170 const int counter = function.deoptimization_counter();
173 TimelineEvent* timeline_event = compiler_stream->StartEvent(); 171 TimelineEvent* timeline_event = compiler_stream->StartEvent();
174 if (timeline_event != NULL) { 172 if (timeline_event != NULL) {
175 timeline_event->Duration("Deoptimize", 173 timeline_event->Duration("Deoptimize", deopt_start_micros_,
176 deopt_start_micros_,
177 OS::GetCurrentMonotonicMicros()); 174 OS::GetCurrentMonotonicMicros());
178 timeline_event->SetNumArguments(3); 175 timeline_event->SetNumArguments(3);
179 timeline_event->CopyArgument(0, "function", function_name.ToCString()); 176 timeline_event->CopyArgument(0, "function", function_name.ToCString());
180 timeline_event->CopyArgument(1, "reason", reason); 177 timeline_event->CopyArgument(1, "reason", reason);
181 timeline_event->FormatArgument(2, "deoptimizationCount", "%d", counter); 178 timeline_event->FormatArgument(2, "deoptimizationCount", "%d", counter);
182 timeline_event->Complete(); 179 timeline_event->Complete();
183 } 180 }
184 } 181 }
185 } 182 }
186 #endif // !PRODUCT 183 #endif // !PRODUCT
187 } 184 }
188 185
189 186
190 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { 187 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
191 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_)); 188 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_));
192 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_)); 189 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_));
193 190
194 // Visit any object pointers on the destination stack. 191 // Visit any object pointers on the destination stack.
195 if (dest_frame_is_allocated_) { 192 if (dest_frame_is_allocated_) {
196 for (intptr_t i = 0; i < dest_frame_size_; i++) { 193 for (intptr_t i = 0; i < dest_frame_size_; i++) {
197 if (dest_frame_[i] != 0) { 194 if (dest_frame_[i] != 0) {
198 visitor->VisitPointer(reinterpret_cast<RawObject**>(&dest_frame_[i])); 195 visitor->VisitPointer(reinterpret_cast<RawObject**>(&dest_frame_[i]));
199 } 196 }
200 } 197 }
201 } 198 }
202 } 199 }
203 200
204 201
205 intptr_t DeoptContext::DestStackAdjustment() const { 202 intptr_t DeoptContext::DestStackAdjustment() const {
206 return dest_frame_size_ 203 return dest_frame_size_ - kDartFrameFixedSize - num_args_
207 - kDartFrameFixedSize
208 - num_args_
209 #if !defined(TARGET_ARCH_DBC) 204 #if !defined(TARGET_ARCH_DBC)
210 - 1 // For fp. 205 - 1 // For fp.
211 #endif 206 #endif
212 - kParamEndSlotFromFp; 207 - kParamEndSlotFromFp;
213 } 208 }
214 209
215 210
216 intptr_t DeoptContext::GetSourceFp() const { 211 intptr_t DeoptContext::GetSourceFp() const {
217 #if !defined(TARGET_ARCH_DBC) 212 #if !defined(TARGET_ARCH_DBC)
218 return source_frame_[source_frame_size_ - 1 - num_args_ - 213 return source_frame_[source_frame_size_ - 1 - num_args_ -
219 kParamEndSlotFromFp]; 214 kParamEndSlotFromFp];
220 #else 215 #else
221 return source_frame_[num_args_ + kDartFrameFixedSize + 216 return source_frame_[num_args_ + kDartFrameFixedSize +
222 kSavedCallerFpSlotFromFp]; 217 kSavedCallerFpSlotFromFp];
223 #endif 218 #endif
224 } 219 }
225 220
226 221
227 intptr_t DeoptContext::GetSourcePp() const { 222 intptr_t DeoptContext::GetSourcePp() const {
228 #if !defined(TARGET_ARCH_DBC) 223 #if !defined(TARGET_ARCH_DBC)
229 return source_frame_[source_frame_size_ - 1 - num_args_ - 224 return source_frame_[source_frame_size_ - 1 - num_args_ -
230 kParamEndSlotFromFp + 225 kParamEndSlotFromFp +
231 StackFrame::SavedCallerPpSlotFromFp()]; 226 StackFrame::SavedCallerPpSlotFromFp()];
232 #else 227 #else
233 UNREACHABLE(); 228 UNREACHABLE();
234 return 0; 229 return 0;
235 #endif 230 #endif
236 } 231 }
237 232
238 233
239 intptr_t DeoptContext::GetSourcePc() const { 234 intptr_t DeoptContext::GetSourcePc() const {
240 #if !defined(TARGET_ARCH_DBC) 235 #if !defined(TARGET_ARCH_DBC)
241 return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp]; 236 return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp];
242 #else 237 #else
243 return source_frame_[num_args_ + kDartFrameFixedSize + 238 return source_frame_[num_args_ + kDartFrameFixedSize +
244 kSavedCallerPcSlotFromFp]; 239 kSavedCallerPcSlotFromFp];
245 #endif 240 #endif
246 } 241 }
247 242
248 243
249 intptr_t DeoptContext::GetCallerFp() const { 244 intptr_t DeoptContext::GetCallerFp() const {
250 return caller_fp_; 245 return caller_fp_;
251 } 246 }
252 247
253 248
254 void DeoptContext::SetCallerFp(intptr_t caller_fp) { 249 void DeoptContext::SetCallerFp(intptr_t caller_fp) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 // objects until the frame is fully reconstructed and it is safe to perform 307 // objects until the frame is fully reconstructed and it is safe to perform
313 // GC. 308 // GC.
314 // Arguments (class of the instance to allocate and field-value pairs) are 309 // Arguments (class of the instance to allocate and field-value pairs) are
315 // described as part of the expression stack for the bottom-most deoptimized 310 // described as part of the expression stack for the bottom-most deoptimized
316 // frame. They will be used during materialization and removed from the stack 311 // frame. They will be used during materialization and removed from the stack
317 // right before control switches to the unoptimized code. 312 // right before control switches to the unoptimized code.
318 const intptr_t num_materializations = 313 const intptr_t num_materializations =
319 DeoptInfo::NumMaterializations(deopt_instructions); 314 DeoptInfo::NumMaterializations(deopt_instructions);
320 PrepareForDeferredMaterialization(num_materializations); 315 PrepareForDeferredMaterialization(num_materializations);
321 for (intptr_t from_index = 0, to_index = kDartFrameFixedSize; 316 for (intptr_t from_index = 0, to_index = kDartFrameFixedSize;
322 from_index < num_materializations; 317 from_index < num_materializations; from_index++) {
323 from_index++) {
324 const intptr_t field_count = 318 const intptr_t field_count =
325 DeoptInstr::GetFieldCount(deopt_instructions[from_index]); 319 DeoptInstr::GetFieldCount(deopt_instructions[from_index]);
326 intptr_t* args = GetDestFrameAddressAt(to_index); 320 intptr_t* args = GetDestFrameAddressAt(to_index);
327 DeferredObject* obj = new DeferredObject(field_count, args); 321 DeferredObject* obj = new DeferredObject(field_count, args);
328 SetDeferredObjectAt(from_index, obj); 322 SetDeferredObjectAt(from_index, obj);
329 to_index += obj->ArgumentCount(); 323 to_index += obj->ArgumentCount();
330 } 324 }
331 325
332 // Populate stack frames. 326 // Populate stack frames.
333 for (intptr_t to_index = frame_size - 1, from_index = len - 1; 327 for (intptr_t to_index = frame_size - 1, from_index = len - 1; to_index >= 0;
334 to_index >= 0;
335 to_index--, from_index--) { 328 to_index--, from_index--) {
336 intptr_t* to_addr = GetDestFrameAddressAt(to_index); 329 intptr_t* to_addr = GetDestFrameAddressAt(to_index);
337 DeoptInstr* instr = deopt_instructions[from_index]; 330 DeoptInstr* instr = deopt_instructions[from_index];
338 if (!objects_only || IsObjectInstruction(instr->kind())) { 331 if (!objects_only || IsObjectInstruction(instr->kind())) {
339 instr->Execute(this, to_addr); 332 instr->Execute(this, to_addr);
340 } else { 333 } else {
341 *reinterpret_cast<RawObject**>(to_addr) = Object::null(); 334 *reinterpret_cast<RawObject**>(to_addr) = Object::null();
342 } 335 }
343 } 336 }
344 337
345 if (FLAG_trace_deoptimization_verbose) { 338 if (FLAG_trace_deoptimization_verbose) {
346 for (intptr_t i = 0; i < frame_size; i++) { 339 for (intptr_t i = 0; i < frame_size; i++) {
347 intptr_t* to_addr = GetDestFrameAddressAt(i); 340 intptr_t* to_addr = GetDestFrameAddressAt(i);
348 THR_Print("*%" Pd ". [%p] 0x%" Px " [%s]\n", 341 THR_Print("*%" Pd ". [%p] 0x%" Px " [%s]\n", i, to_addr, *to_addr,
349 i,
350 to_addr,
351 *to_addr,
352 deopt_instructions[i + (len - frame_size)]->ToCString()); 342 deopt_instructions[i + (len - frame_size)]->ToCString());
353 } 343 }
354 } 344 }
355 } 345 }
356 346
357 347
358 static void FillDeferredSlots(DeoptContext* deopt_context, 348 static void FillDeferredSlots(DeoptContext* deopt_context,
359 DeferredSlot** slot_list) { 349 DeferredSlot** slot_list) {
360 DeferredSlot* slot = *slot_list; 350 DeferredSlot* slot = *slot_list;
361 *slot_list = NULL; 351 *slot_list = NULL;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 ASSERT(top_frame != NULL); 385 ASSERT(top_frame != NULL);
396 const Code& code = Code::Handle(top_frame->LookupDartCode()); 386 const Code& code = Code::Handle(top_frame->LookupDartCode());
397 const Function& top_function = Function::Handle(code.function()); 387 const Function& top_function = Function::Handle(code.function());
398 const Script& script = Script::Handle(top_function.script()); 388 const Script& script = Script::Handle(top_function.script());
399 const TokenPosition token_pos = code.GetTokenIndexOfPC(top_frame->pc()); 389 const TokenPosition token_pos = code.GetTokenIndexOfPC(top_frame->pc());
400 intptr_t line, column; 390 intptr_t line, column;
401 script.GetTokenLocation(token_pos, &line, &column); 391 script.GetTokenLocation(token_pos, &line, &column);
402 String& line_string = String::Handle(script.GetLine(line)); 392 String& line_string = String::Handle(script.GetLine(line));
403 THR_Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); 393 THR_Print(" Function: %s\n", top_function.ToFullyQualifiedCString());
404 char line_buffer[80]; 394 char line_buffer[80];
405 OS::SNPrint(line_buffer, sizeof(line_buffer), " Line %" Pd ": '%s'", 395 OS::SNPrint(line_buffer, sizeof(line_buffer), " Line %" Pd ": '%s'", line,
406 line, line_string.ToCString()); 396 line_string.ToCString());
407 THR_Print("%s\n", line_buffer); 397 THR_Print("%s\n", line_buffer);
408 THR_Print(" Deopt args: %" Pd "\n", deopt_arg_count); 398 THR_Print(" Deopt args: %" Pd "\n", deopt_arg_count);
409 } 399 }
410 400
411 return deopt_arg_count; 401 return deopt_arg_count;
412 } 402 }
413 403
414 404
415 RawArray* DeoptContext::DestFrameAsArray() { 405 RawArray* DeoptContext::DestFrameAsArray() {
416 ASSERT(dest_frame_ != NULL && dest_frame_is_allocated_); 406 ASSERT(dest_frame_ != NULL && dest_frame_is_allocated_);
417 const Array& dest_array = 407 const Array& dest_array = Array::Handle(zone(), Array::New(dest_frame_size_));
418 Array::Handle(zone(), Array::New(dest_frame_size_));
419 PassiveObject& obj = PassiveObject::Handle(zone()); 408 PassiveObject& obj = PassiveObject::Handle(zone());
420 for (intptr_t i = 0; i < dest_frame_size_; i++) { 409 for (intptr_t i = 0; i < dest_frame_size_; i++) {
421 obj = reinterpret_cast<RawObject*>(dest_frame_[i]); 410 obj = reinterpret_cast<RawObject*>(dest_frame_[i]);
422 dest_array.SetAt(i, obj); 411 dest_array.SetAt(i, obj);
423 } 412 }
424 return dest_array.raw(); 413 return dest_array.raw();
425 } 414 }
426 415
427 416
428 // Deoptimization instruction creating return address using function and 417 // Deoptimization instruction creating return address using function and
429 // deopt-id stored at 'object_table_index'. 418 // deopt-id stored at 'object_table_index'.
430 class DeoptRetAddressInstr : public DeoptInstr { 419 class DeoptRetAddressInstr : public DeoptInstr {
431 public: 420 public:
432 DeoptRetAddressInstr(intptr_t object_table_index, intptr_t deopt_id) 421 DeoptRetAddressInstr(intptr_t object_table_index, intptr_t deopt_id)
433 : object_table_index_(object_table_index), deopt_id_(deopt_id) { 422 : object_table_index_(object_table_index), deopt_id_(deopt_id) {
434 ASSERT(object_table_index >= 0); 423 ASSERT(object_table_index >= 0);
435 ASSERT(deopt_id >= 0); 424 ASSERT(deopt_id >= 0);
436 } 425 }
437 426
438 explicit DeoptRetAddressInstr(intptr_t source_index) 427 explicit DeoptRetAddressInstr(intptr_t source_index)
439 : object_table_index_(ObjectTableIndex::decode(source_index)), 428 : object_table_index_(ObjectTableIndex::decode(source_index)),
440 deopt_id_(DeoptId::decode(source_index)) { 429 deopt_id_(DeoptId::decode(source_index)) {}
441 }
442 430
443 virtual intptr_t source_index() const { 431 virtual intptr_t source_index() const {
444 return ObjectTableIndex::encode(object_table_index_) | 432 return ObjectTableIndex::encode(object_table_index_) |
445 DeoptId::encode(deopt_id_); 433 DeoptId::encode(deopt_id_);
446 } 434 }
447 435
448 virtual DeoptInstr::Kind kind() const { return kRetAddress; } 436 virtual DeoptInstr::Kind kind() const { return kRetAddress; }
449 437
450 virtual const char* ArgumentsToCString() const { 438 virtual const char* ArgumentsToCString() const {
451 return Thread::Current()->zone()->PrintToString( 439 return Thread::Current()->zone()->PrintToString(
452 "%" Pd ", %" Pd "", object_table_index_, deopt_id_); 440 "%" Pd ", %" Pd "", object_table_index_, deopt_id_);
453 } 441 }
454 442
455 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 443 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
456 *dest_addr = Smi::RawValue(0); 444 *dest_addr = Smi::RawValue(0);
457 deopt_context->DeferRetAddrMaterialization( 445 deopt_context->DeferRetAddrMaterialization(object_table_index_, deopt_id_,
458 object_table_index_, deopt_id_, dest_addr); 446 dest_addr);
459 } 447 }
460 448
461 intptr_t object_table_index() const { return object_table_index_; } 449 intptr_t object_table_index() const { return object_table_index_; }
462 intptr_t deopt_id() const { return deopt_id_; } 450 intptr_t deopt_id() const { return deopt_id_; }
463 451
464 private: 452 private:
465 static const intptr_t kFieldWidth = kBitsPerWord / 2; 453 static const intptr_t kFieldWidth = kBitsPerWord / 2;
466 class ObjectTableIndex : 454 class ObjectTableIndex : public BitField<intptr_t, intptr_t, 0, kFieldWidth> {
467 public BitField<intptr_t, intptr_t, 0, kFieldWidth> { }; 455 };
468 class DeoptId : 456 class DeoptId
469 public BitField<intptr_t, intptr_t, kFieldWidth, kFieldWidth> { }; 457 : public BitField<intptr_t, intptr_t, kFieldWidth, kFieldWidth> {};
470 458
471 const intptr_t object_table_index_; 459 const intptr_t object_table_index_;
472 const intptr_t deopt_id_; 460 const intptr_t deopt_id_;
473 461
474 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddressInstr); 462 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddressInstr);
475 }; 463 };
476 464
477 465
478 // Deoptimization instruction moving a constant stored at 'object_table_index'. 466 // Deoptimization instruction moving a constant stored at 'object_table_index'.
479 class DeoptConstantInstr : public DeoptInstr { 467 class DeoptConstantInstr : public DeoptInstr {
480 public: 468 public:
481 explicit DeoptConstantInstr(intptr_t object_table_index) 469 explicit DeoptConstantInstr(intptr_t object_table_index)
482 : object_table_index_(object_table_index) { 470 : object_table_index_(object_table_index) {
483 ASSERT(object_table_index >= 0); 471 ASSERT(object_table_index >= 0);
484 } 472 }
485 473
486 virtual intptr_t source_index() const { return object_table_index_; } 474 virtual intptr_t source_index() const { return object_table_index_; }
487 virtual DeoptInstr::Kind kind() const { return kConstant; } 475 virtual DeoptInstr::Kind kind() const { return kConstant; }
488 476
489 virtual const char* ArgumentsToCString() const { 477 virtual const char* ArgumentsToCString() const {
490 return Thread::Current()->zone()->PrintToString( 478 return Thread::Current()->zone()->PrintToString("%" Pd "",
491 "%" Pd "", object_table_index_); 479 object_table_index_);
492 } 480 }
493 481
494 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 482 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
495 const PassiveObject& obj = PassiveObject::Handle( 483 const PassiveObject& obj = PassiveObject::Handle(
496 deopt_context->zone(), deopt_context->ObjectAt(object_table_index_)); 484 deopt_context->zone(), deopt_context->ObjectAt(object_table_index_));
497 *reinterpret_cast<RawObject**>(dest_addr) = obj.raw(); 485 *reinterpret_cast<RawObject**>(dest_addr) = obj.raw();
498 } 486 }
499 487
500 private: 488 private:
501 const intptr_t object_table_index_; 489 const intptr_t object_table_index_;
502 490
503 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); 491 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr);
504 }; 492 };
505 493
506 494
507 // Deoptimization instruction moving value from optimized frame at 495 // Deoptimization instruction moving value from optimized frame at
508 // 'source_index' to specified slots in the unoptimized frame. 496 // 'source_index' to specified slots in the unoptimized frame.
509 // 'source_index' represents the slot index of the frame (0 being 497 // 'source_index' represents the slot index of the frame (0 being
510 // first argument) and accounts for saved return address, frame 498 // first argument) and accounts for saved return address, frame
511 // pointer, pool pointer and pc marker. 499 // pointer, pool pointer and pc marker.
512 // Deoptimization instruction moving a CPU register. 500 // Deoptimization instruction moving a CPU register.
513 class DeoptWordInstr: public DeoptInstr { 501 class DeoptWordInstr : public DeoptInstr {
514 public: 502 public:
515 explicit DeoptWordInstr(intptr_t source_index) 503 explicit DeoptWordInstr(intptr_t source_index) : source_(source_index) {}
516 : source_(source_index) {}
517 504
518 explicit DeoptWordInstr(const CpuRegisterSource& source) 505 explicit DeoptWordInstr(const CpuRegisterSource& source) : source_(source) {}
519 : source_(source) {}
520 506
521 virtual intptr_t source_index() const { return source_.source_index(); } 507 virtual intptr_t source_index() const { return source_.source_index(); }
522 virtual DeoptInstr::Kind kind() const { return kWord; } 508 virtual DeoptInstr::Kind kind() const { return kWord; }
523 509
524 virtual const char* ArgumentsToCString() const { 510 virtual const char* ArgumentsToCString() const { return source_.ToCString(); }
525 return source_.ToCString();
526 }
527 511
528 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 512 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
529 *dest_addr = source_.Value<intptr_t>(deopt_context); 513 *dest_addr = source_.Value<intptr_t>(deopt_context);
530 } 514 }
531 515
532 private: 516 private:
533 const CpuRegisterSource source_; 517 const CpuRegisterSource source_;
534 518
535 DISALLOW_COPY_AND_ASSIGN(DeoptWordInstr); 519 DISALLOW_COPY_AND_ASSIGN(DeoptWordInstr);
536 }; 520 };
537 521
538 522
539 class DeoptIntegerInstrBase: public DeoptInstr { 523 class DeoptIntegerInstrBase : public DeoptInstr {
540 public: 524 public:
541 DeoptIntegerInstrBase() { } 525 DeoptIntegerInstrBase() {}
542 526
543 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 527 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
544 const int64_t value = GetValue(deopt_context); 528 const int64_t value = GetValue(deopt_context);
545 if (Smi::IsValid(value)) { 529 if (Smi::IsValid(value)) {
546 *dest_addr = Smi::RawValue(static_cast<intptr_t>(value)); 530 *dest_addr = Smi::RawValue(static_cast<intptr_t>(value));
547 } else { 531 } else {
548 *dest_addr = Smi::RawValue(0); 532 *dest_addr = Smi::RawValue(0);
549 deopt_context->DeferMintMaterialization( 533 deopt_context->DeferMintMaterialization(
550 value, reinterpret_cast<RawMint**>(dest_addr)); 534 value, reinterpret_cast<RawMint**>(dest_addr));
551 } 535 }
552 } 536 }
553 537
554 virtual int64_t GetValue(DeoptContext* deopt_context) = 0; 538 virtual int64_t GetValue(DeoptContext* deopt_context) = 0;
555 539
556 private: 540 private:
557 DISALLOW_COPY_AND_ASSIGN(DeoptIntegerInstrBase); 541 DISALLOW_COPY_AND_ASSIGN(DeoptIntegerInstrBase);
558 }; 542 };
559 543
560 544
561 class DeoptMintPairInstr: public DeoptIntegerInstrBase { 545 class DeoptMintPairInstr : public DeoptIntegerInstrBase {
562 public: 546 public:
563 explicit DeoptMintPairInstr(intptr_t source_index) 547 explicit DeoptMintPairInstr(intptr_t source_index)
564 : DeoptIntegerInstrBase(), 548 : DeoptIntegerInstrBase(),
565 lo_(LoRegister::decode(source_index)), 549 lo_(LoRegister::decode(source_index)),
566 hi_(HiRegister::decode(source_index)) { 550 hi_(HiRegister::decode(source_index)) {}
567 }
568 551
569 DeoptMintPairInstr(const CpuRegisterSource& lo, const CpuRegisterSource& hi) 552 DeoptMintPairInstr(const CpuRegisterSource& lo, const CpuRegisterSource& hi)
570 : DeoptIntegerInstrBase(), lo_(lo), hi_(hi) {} 553 : DeoptIntegerInstrBase(), lo_(lo), hi_(hi) {}
571 554
572 virtual intptr_t source_index() const { 555 virtual intptr_t source_index() const {
573 return LoRegister::encode(lo_.source_index()) | 556 return LoRegister::encode(lo_.source_index()) |
574 HiRegister::encode(hi_.source_index()); 557 HiRegister::encode(hi_.source_index());
575 } 558 }
576 virtual DeoptInstr::Kind kind() const { return kMintPair; } 559 virtual DeoptInstr::Kind kind() const { return kMintPair; }
577 560
578 virtual const char* ArgumentsToCString() const { 561 virtual const char* ArgumentsToCString() const {
579 return Thread::Current()->zone()->PrintToString( 562 return Thread::Current()->zone()->PrintToString("%s,%s", lo_.ToCString(),
580 "%s,%s", 563 hi_.ToCString());
581 lo_.ToCString(),
582 hi_.ToCString());
583 } 564 }
584 565
585 virtual int64_t GetValue(DeoptContext* deopt_context) { 566 virtual int64_t GetValue(DeoptContext* deopt_context) {
586 return Utils::LowHighTo64Bits( 567 return Utils::LowHighTo64Bits(lo_.Value<uint32_t>(deopt_context),
587 lo_.Value<uint32_t>(deopt_context), hi_.Value<int32_t>(deopt_context)); 568 hi_.Value<int32_t>(deopt_context));
588 } 569 }
589 570
590 private: 571 private:
591 static const intptr_t kFieldWidth = kBitsPerWord / 2; 572 static const intptr_t kFieldWidth = kBitsPerWord / 2;
592 class LoRegister : public BitField<intptr_t, intptr_t, 0, kFieldWidth> { }; 573 class LoRegister : public BitField<intptr_t, intptr_t, 0, kFieldWidth> {};
593 class HiRegister : 574 class HiRegister
594 public BitField<intptr_t, intptr_t, kFieldWidth, kFieldWidth> { }; 575 : public BitField<intptr_t, intptr_t, kFieldWidth, kFieldWidth> {};
595 576
596 const CpuRegisterSource lo_; 577 const CpuRegisterSource lo_;
597 const CpuRegisterSource hi_; 578 const CpuRegisterSource hi_;
598 579
599 DISALLOW_COPY_AND_ASSIGN(DeoptMintPairInstr); 580 DISALLOW_COPY_AND_ASSIGN(DeoptMintPairInstr);
600 }; 581 };
601 582
602 583
603 template<DeoptInstr::Kind K, typename T> 584 template <DeoptInstr::Kind K, typename T>
604 class DeoptIntInstr : public DeoptIntegerInstrBase { 585 class DeoptIntInstr : public DeoptIntegerInstrBase {
605 public: 586 public:
606 explicit DeoptIntInstr(intptr_t source_index) 587 explicit DeoptIntInstr(intptr_t source_index)
607 : DeoptIntegerInstrBase(), source_(source_index) { 588 : DeoptIntegerInstrBase(), source_(source_index) {}
608 }
609 589
610 explicit DeoptIntInstr(const CpuRegisterSource& source) 590 explicit DeoptIntInstr(const CpuRegisterSource& source)
611 : DeoptIntegerInstrBase(), source_(source) { 591 : DeoptIntegerInstrBase(), source_(source) {}
612 }
613 592
614 virtual intptr_t source_index() const { return source_.source_index(); } 593 virtual intptr_t source_index() const { return source_.source_index(); }
615 virtual DeoptInstr::Kind kind() const { return K; } 594 virtual DeoptInstr::Kind kind() const { return K; }
616 595
617 virtual const char* ArgumentsToCString() const { 596 virtual const char* ArgumentsToCString() const { return source_.ToCString(); }
618 return source_.ToCString();
619 }
620 597
621 virtual int64_t GetValue(DeoptContext* deopt_context) { 598 virtual int64_t GetValue(DeoptContext* deopt_context) {
622 return static_cast<int64_t>(source_.Value<T>(deopt_context)); 599 return static_cast<int64_t>(source_.Value<T>(deopt_context));
623 } 600 }
624 601
625 private: 602 private:
626 const CpuRegisterSource source_; 603 const CpuRegisterSource source_;
627 604
628 DISALLOW_COPY_AND_ASSIGN(DeoptIntInstr); 605 DISALLOW_COPY_AND_ASSIGN(DeoptIntInstr);
629 }; 606 };
630 607
631 608
632 typedef DeoptIntInstr<DeoptInstr::kUint32, uint32_t> DeoptUint32Instr; 609 typedef DeoptIntInstr<DeoptInstr::kUint32, uint32_t> DeoptUint32Instr;
633 typedef DeoptIntInstr<DeoptInstr::kInt32, int32_t> DeoptInt32Instr; 610 typedef DeoptIntInstr<DeoptInstr::kInt32, int32_t> DeoptInt32Instr;
634 typedef DeoptIntInstr<DeoptInstr::kMint, int64_t> DeoptMintInstr; 611 typedef DeoptIntInstr<DeoptInstr::kMint, int64_t> DeoptMintInstr;
635 612
636 613
637 template<DeoptInstr::Kind K, 614 template <DeoptInstr::Kind K, typename Type, typename RawObjectType>
638 typename Type, 615 class DeoptFpuInstr : public DeoptInstr {
639 typename RawObjectType>
640 class DeoptFpuInstr: public DeoptInstr {
641 public: 616 public:
642 explicit DeoptFpuInstr(intptr_t source_index) 617 explicit DeoptFpuInstr(intptr_t source_index) : source_(source_index) {}
643 : source_(source_index) {}
644 618
645 explicit DeoptFpuInstr(const FpuRegisterSource& source) 619 explicit DeoptFpuInstr(const FpuRegisterSource& source) : source_(source) {}
646 : source_(source) {}
647 620
648 virtual intptr_t source_index() const { return source_.source_index(); } 621 virtual intptr_t source_index() const { return source_.source_index(); }
649 virtual DeoptInstr::Kind kind() const { return K; } 622 virtual DeoptInstr::Kind kind() const { return K; }
650 623
651 virtual const char* ArgumentsToCString() const { 624 virtual const char* ArgumentsToCString() const { return source_.ToCString(); }
652 return source_.ToCString();
653 }
654 625
655 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 626 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
656 *dest_addr = Smi::RawValue(0); 627 *dest_addr = Smi::RawValue(0);
657 deopt_context->DeferMaterialization( 628 deopt_context->DeferMaterialization(
658 source_.Value<Type>(deopt_context), 629 source_.Value<Type>(deopt_context),
659 reinterpret_cast<RawObjectType**>(dest_addr)); 630 reinterpret_cast<RawObjectType**>(dest_addr));
660 } 631 }
661 632
662 private: 633 private:
663 const FpuRegisterSource source_; 634 const FpuRegisterSource source_;
(...skipping 19 matching lines...) Expand all
683 public: 654 public:
684 explicit DeoptPcMarkerInstr(intptr_t object_table_index) 655 explicit DeoptPcMarkerInstr(intptr_t object_table_index)
685 : object_table_index_(object_table_index) { 656 : object_table_index_(object_table_index) {
686 ASSERT(object_table_index >= 0); 657 ASSERT(object_table_index >= 0);
687 } 658 }
688 659
689 virtual intptr_t source_index() const { return object_table_index_; } 660 virtual intptr_t source_index() const { return object_table_index_; }
690 virtual DeoptInstr::Kind kind() const { return kPcMarker; } 661 virtual DeoptInstr::Kind kind() const { return kPcMarker; }
691 662
692 virtual const char* ArgumentsToCString() const { 663 virtual const char* ArgumentsToCString() const {
693 return Thread::Current()->zone()->PrintToString( 664 return Thread::Current()->zone()->PrintToString("%" Pd "",
694 "%" Pd "", object_table_index_); 665 object_table_index_);
695 } 666 }
696 667
697 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 668 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
698 Function& function = Function::Handle(deopt_context->zone()); 669 Function& function = Function::Handle(deopt_context->zone());
699 function ^= deopt_context->ObjectAt(object_table_index_); 670 function ^= deopt_context->ObjectAt(object_table_index_);
700 if (function.IsNull()) { 671 if (function.IsNull()) {
701 *reinterpret_cast<RawObject**>(dest_addr) = deopt_context->is_lazy_deopt() 672 *reinterpret_cast<RawObject**>(dest_addr) =
702 ? StubCode::DeoptimizeLazyFromReturn_entry()->code() 673 deopt_context->is_lazy_deopt()
703 : StubCode::Deoptimize_entry()->code(); 674 ? StubCode::DeoptimizeLazyFromReturn_entry()->code()
675 : StubCode::Deoptimize_entry()->code();
704 return; 676 return;
705 } 677 }
706 678
707 // We don't always have the Code object for the frame's corresponding 679 // We don't always have the Code object for the frame's corresponding
708 // unoptimized code as it may have been collected. Use a stub as the pc 680 // unoptimized code as it may have been collected. Use a stub as the pc
709 // marker until we can recreate that Code object during deferred 681 // marker until we can recreate that Code object during deferred
710 // materialization to maintain the invariant that Dart frames always have 682 // materialization to maintain the invariant that Dart frames always have
711 // a pc marker. 683 // a pc marker.
712 *reinterpret_cast<RawObject**>(dest_addr) = 684 *reinterpret_cast<RawObject**>(dest_addr) =
713 StubCode::FrameAwaitingMaterialization_entry()->code(); 685 StubCode::FrameAwaitingMaterialization_entry()->code();
(...skipping 13 matching lines...) Expand all
727 public: 699 public:
728 explicit DeoptPpInstr(intptr_t object_table_index) 700 explicit DeoptPpInstr(intptr_t object_table_index)
729 : object_table_index_(object_table_index) { 701 : object_table_index_(object_table_index) {
730 ASSERT(object_table_index >= 0); 702 ASSERT(object_table_index >= 0);
731 } 703 }
732 704
733 virtual intptr_t source_index() const { return object_table_index_; } 705 virtual intptr_t source_index() const { return object_table_index_; }
734 virtual DeoptInstr::Kind kind() const { return kPp; } 706 virtual DeoptInstr::Kind kind() const { return kPp; }
735 707
736 virtual const char* ArgumentsToCString() const { 708 virtual const char* ArgumentsToCString() const {
737 return Thread::Current()->zone()->PrintToString( 709 return Thread::Current()->zone()->PrintToString("%" Pd "",
738 "%" Pd "", object_table_index_); 710 object_table_index_);
739 } 711 }
740 712
741 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 713 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
742 *dest_addr = Smi::RawValue(0); 714 *dest_addr = Smi::RawValue(0);
743 deopt_context->DeferPpMaterialization(object_table_index_, 715 deopt_context->DeferPpMaterialization(
744 reinterpret_cast<RawObject**>(dest_addr)); 716 object_table_index_, reinterpret_cast<RawObject**>(dest_addr));
745 } 717 }
746 718
747 private: 719 private:
748 intptr_t object_table_index_; 720 intptr_t object_table_index_;
749 721
750 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr); 722 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr);
751 }; 723 };
752 724
753 725
754 // Deoptimization instruction copying the caller saved FP from optimized frame. 726 // Deoptimization instruction copying the caller saved FP from optimized frame.
755 class DeoptCallerFpInstr : public DeoptInstr { 727 class DeoptCallerFpInstr : public DeoptInstr {
756 public: 728 public:
757 DeoptCallerFpInstr() {} 729 DeoptCallerFpInstr() {}
758 730
759 virtual intptr_t source_index() const { return 0; } 731 virtual intptr_t source_index() const { return 0; }
760 virtual DeoptInstr::Kind kind() const { return kCallerFp; } 732 virtual DeoptInstr::Kind kind() const { return kCallerFp; }
761 733
762 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 734 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
763 *dest_addr = deopt_context->GetCallerFp(); 735 *dest_addr = deopt_context->GetCallerFp();
764 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( 736 deopt_context->SetCallerFp(
765 dest_addr - kSavedCallerFpSlotFromFp)); 737 reinterpret_cast<intptr_t>(dest_addr - kSavedCallerFpSlotFromFp));
766 } 738 }
767 739
768 private: 740 private:
769 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); 741 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr);
770 }; 742 };
771 743
772 744
773 // Deoptimization instruction copying the caller saved PP from optimized frame. 745 // Deoptimization instruction copying the caller saved PP from optimized frame.
774 class DeoptCallerPpInstr : public DeoptInstr { 746 class DeoptCallerPpInstr : public DeoptInstr {
775 public: 747 public:
(...skipping 26 matching lines...) Expand all
802 774
803 private: 775 private:
804 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); 776 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr);
805 }; 777 };
806 778
807 779
808 // Write reference to a materialized object with the given index into the 780 // Write reference to a materialized object with the given index into the
809 // stack slot. 781 // stack slot.
810 class DeoptMaterializedObjectRefInstr : public DeoptInstr { 782 class DeoptMaterializedObjectRefInstr : public DeoptInstr {
811 public: 783 public:
812 explicit DeoptMaterializedObjectRefInstr(intptr_t index) 784 explicit DeoptMaterializedObjectRefInstr(intptr_t index) : index_(index) {
813 : index_(index) {
814 ASSERT(index >= 0); 785 ASSERT(index >= 0);
815 } 786 }
816 787
817 virtual intptr_t source_index() const { return index_; } 788 virtual intptr_t source_index() const { return index_; }
818 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; } 789 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; }
819 790
820 virtual const char* ArgumentsToCString() const { 791 virtual const char* ArgumentsToCString() const {
821 return Thread::Current()->zone()->PrintToString( 792 return Thread::Current()->zone()->PrintToString("#%" Pd "", index_);
822 "#%" Pd "", index_);
823 } 793 }
824 794
825 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 795 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
826 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); 796 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
827 deopt_context->DeferMaterializedObjectRef( 797 deopt_context->DeferMaterializedObjectRef(index_, dest_addr);
828 index_, dest_addr);
829 } 798 }
830 799
831 private: 800 private:
832 intptr_t index_; 801 intptr_t index_;
833 802
834 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr); 803 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr);
835 }; 804 };
836 805
837 806
838 // Materialize object with the given number of fields. 807 // Materialize object with the given number of fields.
839 // Arguments for materialization (class and field-value pairs) are pushed 808 // Arguments for materialization (class and field-value pairs) are pushed
840 // to the expression stack of the bottom-most frame. 809 // to the expression stack of the bottom-most frame.
841 class DeoptMaterializeObjectInstr : public DeoptInstr { 810 class DeoptMaterializeObjectInstr : public DeoptInstr {
842 public: 811 public:
843 explicit DeoptMaterializeObjectInstr(intptr_t field_count) 812 explicit DeoptMaterializeObjectInstr(intptr_t field_count)
844 : field_count_(field_count) { 813 : field_count_(field_count) {
845 ASSERT(field_count >= 0); 814 ASSERT(field_count >= 0);
846 } 815 }
847 816
848 virtual intptr_t source_index() const { return field_count_; } 817 virtual intptr_t source_index() const { return field_count_; }
849 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; } 818 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; }
850 819
851 virtual const char* ArgumentsToCString() const { 820 virtual const char* ArgumentsToCString() const {
852 return Thread::Current()->zone()->PrintToString( 821 return Thread::Current()->zone()->PrintToString("%" Pd "", field_count_);
853 "%" Pd "", field_count_);
854 } 822 }
855 823
856 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 824 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
857 // This instructions are executed manually by the DeoptimizeWithDeoptInfo. 825 // This instructions are executed manually by the DeoptimizeWithDeoptInfo.
858 UNREACHABLE(); 826 UNREACHABLE();
859 } 827 }
860 828
861 private: 829 private:
862 intptr_t field_count_; 830 intptr_t field_count_;
863 831
864 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializeObjectInstr); 832 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializeObjectInstr);
865 }; 833 };
866 834
867 835
868 uword DeoptInstr::GetRetAddress(DeoptInstr* instr, 836 uword DeoptInstr::GetRetAddress(DeoptInstr* instr,
869 const ObjectPool& object_table, 837 const ObjectPool& object_table,
870 Code* code) { 838 Code* code) {
871 ASSERT(instr->kind() == kRetAddress); 839 ASSERT(instr->kind() == kRetAddress);
872 DeoptRetAddressInstr* ret_address_instr = 840 DeoptRetAddressInstr* ret_address_instr =
873 static_cast<DeoptRetAddressInstr*>(instr); 841 static_cast<DeoptRetAddressInstr*>(instr);
874 // The following assert may trigger when displaying a backtrace 842 // The following assert may trigger when displaying a backtrace
875 // from the simulator. 843 // from the simulator.
876 ASSERT(Thread::IsDeoptAfter(ret_address_instr->deopt_id())); 844 ASSERT(Thread::IsDeoptAfter(ret_address_instr->deopt_id()));
877 ASSERT(!object_table.IsNull()); 845 ASSERT(!object_table.IsNull());
878 Thread* thread = Thread::Current(); 846 Thread* thread = Thread::Current();
879 Zone* zone = thread->zone(); 847 Zone* zone = thread->zone();
880 Function& function = Function::Handle(zone); 848 Function& function = Function::Handle(zone);
881 function ^= object_table.ObjectAt(ret_address_instr->object_table_index()); 849 function ^= object_table.ObjectAt(ret_address_instr->object_table_index());
882 ASSERT(code != NULL); 850 ASSERT(code != NULL);
883 const Error& error = Error::Handle(zone, 851 const Error& error =
884 Compiler::EnsureUnoptimizedCode(thread, function)); 852 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function));
885 if (!error.IsNull()) { 853 if (!error.IsNull()) {
886 Exceptions::PropagateError(error); 854 Exceptions::PropagateError(error);
887 } 855 }
888 *code ^= function.unoptimized_code(); 856 *code ^= function.unoptimized_code();
889 ASSERT(!code->IsNull()); 857 ASSERT(!code->IsNull());
890 uword res = code->GetPcForDeoptId(ret_address_instr->deopt_id(), 858 uword res = code->GetPcForDeoptId(ret_address_instr->deopt_id(),
891 RawPcDescriptors::kDeopt); 859 RawPcDescriptors::kDeopt);
892 ASSERT(res != 0); 860 ASSERT(res != 0);
893 return res; 861 return res;
894 } 862 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 } 947 }
980 UNREACHABLE(); 948 UNREACHABLE();
981 return NULL; 949 return NULL;
982 } 950 }
983 951
984 952
985 class DeoptInfoBuilder::TrieNode : public ZoneAllocated { 953 class DeoptInfoBuilder::TrieNode : public ZoneAllocated {
986 public: 954 public:
987 // Construct the root node representing the implicit "shared" terminator 955 // Construct the root node representing the implicit "shared" terminator
988 // at the end of each deopt info. 956 // at the end of each deopt info.
989 TrieNode() : instruction_(NULL), info_number_(-1), children_(16) { } 957 TrieNode() : instruction_(NULL), info_number_(-1), children_(16) {}
990 958
991 // Construct a node representing a written instruction. 959 // Construct a node representing a written instruction.
992 TrieNode(DeoptInstr* instruction, intptr_t info_number) 960 TrieNode(DeoptInstr* instruction, intptr_t info_number)
993 : instruction_(instruction), info_number_(info_number), children_(4) { } 961 : instruction_(instruction), info_number_(info_number), children_(4) {}
994 962
995 intptr_t info_number() const { return info_number_; } 963 intptr_t info_number() const { return info_number_; }
996 964
997 void AddChild(TrieNode* child) { 965 void AddChild(TrieNode* child) {
998 if (child != NULL) children_.Add(child); 966 if (child != NULL) children_.Add(child);
999 } 967 }
1000 968
1001 TrieNode* FindChild(const DeoptInstr& instruction) { 969 TrieNode* FindChild(const DeoptInstr& instruction) {
1002 for (intptr_t i = 0; i < children_.length(); ++i) { 970 for (intptr_t i = 0; i < children_.length(); ++i) {
1003 TrieNode* child = children_[i]; 971 TrieNode* child = children_[i];
1004 if (child->instruction_->Equals(instruction)) return child; 972 if (child->instruction_->Equals(instruction)) return child;
1005 } 973 }
1006 return NULL; 974 return NULL;
1007 } 975 }
1008 976
1009 private: 977 private:
1010 const DeoptInstr* instruction_; // Instruction that was written. 978 const DeoptInstr* instruction_; // Instruction that was written.
1011 const intptr_t info_number_; // Index of the deopt info it was written to. 979 const intptr_t info_number_; // Index of the deopt info it was written to.
1012 980
1013 GrowableArray<TrieNode*> children_; 981 GrowableArray<TrieNode*> children_;
1014 }; 982 };
1015 983
1016 984
1017 DeoptInfoBuilder::DeoptInfoBuilder(Zone* zone, 985 DeoptInfoBuilder::DeoptInfoBuilder(Zone* zone,
1018 const intptr_t num_args, 986 const intptr_t num_args,
1019 Assembler* assembler) 987 Assembler* assembler)
1020 : zone_(zone), 988 : zone_(zone),
1021 instructions_(), 989 instructions_(),
1022 num_args_(num_args), 990 num_args_(num_args),
1023 assembler_(assembler), 991 assembler_(assembler),
1024 trie_root_(new(zone) TrieNode()), 992 trie_root_(new (zone) TrieNode()),
1025 current_info_number_(0), 993 current_info_number_(0),
1026 frame_start_(-1), 994 frame_start_(-1),
1027 materializations_() { 995 materializations_() {}
1028 }
1029 996
1030 997
1031 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const { 998 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const {
1032 return assembler_->object_pool_wrapper().FindObject(obj); 999 return assembler_->object_pool_wrapper().FindObject(obj);
1033 } 1000 }
1034 1001
1035 1002
1036 intptr_t DeoptInfoBuilder::CalculateStackIndex( 1003 intptr_t DeoptInfoBuilder::CalculateStackIndex(
1037 const Location& source_loc) const { 1004 const Location& source_loc) const {
1038 return source_loc.stack_index() < 0 ? 1005 return source_loc.stack_index() < 0
1039 source_loc.stack_index() + num_args_ : 1006 ? source_loc.stack_index() + num_args_
1040 source_loc.stack_index() + num_args_ + kDartFrameFixedSize; 1007 : source_loc.stack_index() + num_args_ + kDartFrameFixedSize;
1041 } 1008 }
1042 1009
1043 1010
1044 CpuRegisterSource DeoptInfoBuilder::ToCpuRegisterSource(const Location& loc) { 1011 CpuRegisterSource DeoptInfoBuilder::ToCpuRegisterSource(const Location& loc) {
1045 if (loc.IsRegister()) { 1012 if (loc.IsRegister()) {
1046 return CpuRegisterSource(CpuRegisterSource::kRegister, loc.reg()); 1013 return CpuRegisterSource(CpuRegisterSource::kRegister, loc.reg());
1047 } else { 1014 } else {
1048 ASSERT(loc.IsStackSlot()); 1015 ASSERT(loc.IsStackSlot());
1049 return CpuRegisterSource( 1016 return CpuRegisterSource(CpuRegisterSource::kStackSlot,
1050 CpuRegisterSource::kStackSlot, CalculateStackIndex(loc)); 1017 CalculateStackIndex(loc));
1051 } 1018 }
1052 } 1019 }
1053 1020
1054 1021
1055 FpuRegisterSource DeoptInfoBuilder::ToFpuRegisterSource( 1022 FpuRegisterSource DeoptInfoBuilder::ToFpuRegisterSource(
1056 const Location& loc, 1023 const Location& loc,
1057 Location::Kind stack_slot_kind) { 1024 Location::Kind stack_slot_kind) {
1058 if (loc.IsFpuRegister()) { 1025 if (loc.IsFpuRegister()) {
1059 return FpuRegisterSource(FpuRegisterSource::kRegister, loc.fpu_reg()); 1026 return FpuRegisterSource(FpuRegisterSource::kRegister, loc.fpu_reg());
1060 #if defined(TARGET_ARCH_DBC) 1027 #if defined(TARGET_ARCH_DBC)
1061 } else if (loc.IsRegister()) { 1028 } else if (loc.IsRegister()) {
1062 return FpuRegisterSource(FpuRegisterSource::kRegister, loc.reg()); 1029 return FpuRegisterSource(FpuRegisterSource::kRegister, loc.reg());
1063 #endif 1030 #endif
1064 } else { 1031 } else {
1065 ASSERT((stack_slot_kind == Location::kQuadStackSlot) || 1032 ASSERT((stack_slot_kind == Location::kQuadStackSlot) ||
1066 (stack_slot_kind == Location::kDoubleStackSlot)); 1033 (stack_slot_kind == Location::kDoubleStackSlot));
1067 ASSERT(loc.kind() == stack_slot_kind); 1034 ASSERT(loc.kind() == stack_slot_kind);
1068 return FpuRegisterSource( 1035 return FpuRegisterSource(FpuRegisterSource::kStackSlot,
1069 FpuRegisterSource::kStackSlot, CalculateStackIndex(loc)); 1036 CalculateStackIndex(loc));
1070 } 1037 }
1071 } 1038 }
1072 1039
1073 void DeoptInfoBuilder::AddReturnAddress(const Function& function, 1040 void DeoptInfoBuilder::AddReturnAddress(const Function& function,
1074 intptr_t deopt_id, 1041 intptr_t deopt_id,
1075 intptr_t dest_index) { 1042 intptr_t dest_index) {
1076 const intptr_t object_table_index = FindOrAddObjectInTable(function); 1043 const intptr_t object_table_index = FindOrAddObjectInTable(function);
1077 ASSERT(dest_index == FrameSize()); 1044 ASSERT(dest_index == FrameSize());
1078 instructions_.Add( 1045 instructions_.Add(new (zone())
1079 new(zone()) DeoptRetAddressInstr(object_table_index, deopt_id)); 1046 DeoptRetAddressInstr(object_table_index, deopt_id));
1080 } 1047 }
1081 1048
1082 1049
1083 void DeoptInfoBuilder::AddPcMarker(const Function& function, 1050 void DeoptInfoBuilder::AddPcMarker(const Function& function,
1084 intptr_t dest_index) { 1051 intptr_t dest_index) {
1085 intptr_t object_table_index = FindOrAddObjectInTable(function); 1052 intptr_t object_table_index = FindOrAddObjectInTable(function);
1086 ASSERT(dest_index == FrameSize()); 1053 ASSERT(dest_index == FrameSize());
1087 instructions_.Add(new(zone()) DeoptPcMarkerInstr(object_table_index)); 1054 instructions_.Add(new (zone()) DeoptPcMarkerInstr(object_table_index));
1088 } 1055 }
1089 1056
1090 1057
1091 void DeoptInfoBuilder::AddPp(const Function& function, 1058 void DeoptInfoBuilder::AddPp(const Function& function, intptr_t dest_index) {
1092 intptr_t dest_index) {
1093 intptr_t object_table_index = FindOrAddObjectInTable(function); 1059 intptr_t object_table_index = FindOrAddObjectInTable(function);
1094 ASSERT(dest_index == FrameSize()); 1060 ASSERT(dest_index == FrameSize());
1095 instructions_.Add(new(zone()) DeoptPpInstr(object_table_index)); 1061 instructions_.Add(new (zone()) DeoptPpInstr(object_table_index));
1096 } 1062 }
1097 1063
1098 1064
1099 void DeoptInfoBuilder::AddCopy(Value* value, 1065 void DeoptInfoBuilder::AddCopy(Value* value,
1100 const Location& source_loc, 1066 const Location& source_loc,
1101 const intptr_t dest_index) { 1067 const intptr_t dest_index) {
1102 DeoptInstr* deopt_instr = NULL; 1068 DeoptInstr* deopt_instr = NULL;
1103 if (source_loc.IsConstant()) { 1069 if (source_loc.IsConstant()) {
1104 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); 1070 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant());
1105 deopt_instr = new(zone()) DeoptConstantInstr(object_table_index); 1071 deopt_instr = new (zone()) DeoptConstantInstr(object_table_index);
1106 } else if (source_loc.IsInvalid() && 1072 } else if (source_loc.IsInvalid() &&
1107 value->definition()->IsMaterializeObject()) { 1073 value->definition()->IsMaterializeObject()) {
1108 const intptr_t index = FindMaterialization( 1074 const intptr_t index =
1109 value->definition()->AsMaterializeObject()); 1075 FindMaterialization(value->definition()->AsMaterializeObject());
1110 ASSERT(index >= 0); 1076 ASSERT(index >= 0);
1111 deopt_instr = new(zone()) DeoptMaterializedObjectRefInstr(index); 1077 deopt_instr = new (zone()) DeoptMaterializedObjectRefInstr(index);
1112 } else { 1078 } else {
1113 ASSERT(!source_loc.IsInvalid()); 1079 ASSERT(!source_loc.IsInvalid());
1114 switch (value->definition()->representation()) { 1080 switch (value->definition()->representation()) {
1115 case kTagged: 1081 case kTagged:
1116 deopt_instr = new(zone()) DeoptWordInstr( 1082 deopt_instr =
1117 ToCpuRegisterSource(source_loc)); 1083 new (zone()) DeoptWordInstr(ToCpuRegisterSource(source_loc));
1118 break; 1084 break;
1119 case kUnboxedMint: { 1085 case kUnboxedMint: {
1120 if (source_loc.IsPairLocation()) { 1086 if (source_loc.IsPairLocation()) {
1121 PairLocation* pair = source_loc.AsPairLocation(); 1087 PairLocation* pair = source_loc.AsPairLocation();
1122 deopt_instr = new(zone()) DeoptMintPairInstr( 1088 deopt_instr =
1123 ToCpuRegisterSource(pair->At(0)), 1089 new (zone()) DeoptMintPairInstr(ToCpuRegisterSource(pair->At(0)),
1124 ToCpuRegisterSource(pair->At(1))); 1090 ToCpuRegisterSource(pair->At(1)));
1125 } else { 1091 } else {
1126 ASSERT(!source_loc.IsPairLocation()); 1092 ASSERT(!source_loc.IsPairLocation());
1127 deopt_instr = new(zone()) DeoptMintInstr( 1093 deopt_instr =
1128 ToCpuRegisterSource(source_loc)); 1094 new (zone()) DeoptMintInstr(ToCpuRegisterSource(source_loc));
1129 } 1095 }
1130 break; 1096 break;
1131 } 1097 }
1132 case kUnboxedInt32: 1098 case kUnboxedInt32:
1133 deopt_instr = new(zone()) DeoptInt32Instr( 1099 deopt_instr =
1134 ToCpuRegisterSource(source_loc)); 1100 new (zone()) DeoptInt32Instr(ToCpuRegisterSource(source_loc));
1135 break; 1101 break;
1136 case kUnboxedUint32: 1102 case kUnboxedUint32:
1137 deopt_instr = new(zone()) DeoptUint32Instr( 1103 deopt_instr =
1138 ToCpuRegisterSource(source_loc)); 1104 new (zone()) DeoptUint32Instr(ToCpuRegisterSource(source_loc));
1139 break; 1105 break;
1140 case kUnboxedDouble: 1106 case kUnboxedDouble:
1141 deopt_instr = new(zone()) DeoptDoubleInstr( 1107 deopt_instr = new (zone()) DeoptDoubleInstr(
1142 ToFpuRegisterSource(source_loc, Location::kDoubleStackSlot)); 1108 ToFpuRegisterSource(source_loc, Location::kDoubleStackSlot));
1143 break; 1109 break;
1144 case kUnboxedFloat32x4: 1110 case kUnboxedFloat32x4:
1145 deopt_instr = new(zone()) DeoptFloat32x4Instr( 1111 deopt_instr = new (zone()) DeoptFloat32x4Instr(
1146 ToFpuRegisterSource(source_loc, Location::kQuadStackSlot)); 1112 ToFpuRegisterSource(source_loc, Location::kQuadStackSlot));
1147 break; 1113 break;
1148 case kUnboxedFloat64x2: 1114 case kUnboxedFloat64x2:
1149 deopt_instr = new(zone()) DeoptFloat64x2Instr( 1115 deopt_instr = new (zone()) DeoptFloat64x2Instr(
1150 ToFpuRegisterSource(source_loc, Location::kQuadStackSlot)); 1116 ToFpuRegisterSource(source_loc, Location::kQuadStackSlot));
1151 break; 1117 break;
1152 case kUnboxedInt32x4: 1118 case kUnboxedInt32x4:
1153 deopt_instr = new(zone()) DeoptInt32x4Instr( 1119 deopt_instr = new (zone()) DeoptInt32x4Instr(
1154 ToFpuRegisterSource(source_loc, Location::kQuadStackSlot)); 1120 ToFpuRegisterSource(source_loc, Location::kQuadStackSlot));
1155 break; 1121 break;
1156 default: 1122 default:
1157 UNREACHABLE(); 1123 UNREACHABLE();
1158 break; 1124 break;
1159 } 1125 }
1160 } 1126 }
1161 ASSERT(dest_index == FrameSize()); 1127 ASSERT(dest_index == FrameSize());
1162 ASSERT(deopt_instr != NULL); 1128 ASSERT(deopt_instr != NULL);
1163 instructions_.Add(deopt_instr); 1129 instructions_.Add(deopt_instr);
1164 } 1130 }
1165 1131
1166 1132
1167 void DeoptInfoBuilder::AddCallerFp(intptr_t dest_index) { 1133 void DeoptInfoBuilder::AddCallerFp(intptr_t dest_index) {
1168 ASSERT(dest_index == FrameSize()); 1134 ASSERT(dest_index == FrameSize());
1169 instructions_.Add(new(zone()) DeoptCallerFpInstr()); 1135 instructions_.Add(new (zone()) DeoptCallerFpInstr());
1170 } 1136 }
1171 1137
1172 1138
1173 void DeoptInfoBuilder::AddCallerPp(intptr_t dest_index) { 1139 void DeoptInfoBuilder::AddCallerPp(intptr_t dest_index) {
1174 ASSERT(dest_index == FrameSize()); 1140 ASSERT(dest_index == FrameSize());
1175 instructions_.Add(new(zone()) DeoptCallerPpInstr()); 1141 instructions_.Add(new (zone()) DeoptCallerPpInstr());
1176 } 1142 }
1177 1143
1178 1144
1179 void DeoptInfoBuilder::AddCallerPc(intptr_t dest_index) { 1145 void DeoptInfoBuilder::AddCallerPc(intptr_t dest_index) {
1180 ASSERT(dest_index == FrameSize()); 1146 ASSERT(dest_index == FrameSize());
1181 instructions_.Add(new(zone()) DeoptCallerPcInstr()); 1147 instructions_.Add(new (zone()) DeoptCallerPcInstr());
1182 } 1148 }
1183 1149
1184 1150
1185 void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t dest_index) { 1151 void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t dest_index) {
1186 ASSERT(dest_index == FrameSize()); 1152 ASSERT(dest_index == FrameSize());
1187 intptr_t object_table_index = FindOrAddObjectInTable(obj); 1153 intptr_t object_table_index = FindOrAddObjectInTable(obj);
1188 instructions_.Add(new(zone()) DeoptConstantInstr(object_table_index)); 1154 instructions_.Add(new (zone()) DeoptConstantInstr(object_table_index));
1189 } 1155 }
1190 1156
1191 1157
1192 void DeoptInfoBuilder::AddMaterialization(MaterializeObjectInstr* mat) { 1158 void DeoptInfoBuilder::AddMaterialization(MaterializeObjectInstr* mat) {
1193 const intptr_t index = FindMaterialization(mat); 1159 const intptr_t index = FindMaterialization(mat);
1194 if (index >= 0) { 1160 if (index >= 0) {
1195 return; // Already added. 1161 return; // Already added.
1196 } 1162 }
1197 materializations_.Add(mat); 1163 materializations_.Add(mat);
1198 1164
1199 // Count initialized fields and emit kMaterializeObject instruction. 1165 // Count initialized fields and emit kMaterializeObject instruction.
1200 // There is no need to write nulls into fields because object is null 1166 // There is no need to write nulls into fields because object is null
1201 // initialized by default. 1167 // initialized by default.
1202 intptr_t non_null_fields = 0; 1168 intptr_t non_null_fields = 0;
1203 for (intptr_t i = 0; i < mat->InputCount(); i++) { 1169 for (intptr_t i = 0; i < mat->InputCount(); i++) {
1204 if (!mat->InputAt(i)->BindsToConstantNull()) { 1170 if (!mat->InputAt(i)->BindsToConstantNull()) {
1205 non_null_fields++; 1171 non_null_fields++;
1206 } 1172 }
1207 } 1173 }
1208 1174
1209 instructions_.Add( 1175 instructions_.Add(new (zone()) DeoptMaterializeObjectInstr(non_null_fields));
1210 new(zone()) DeoptMaterializeObjectInstr(non_null_fields));
1211 1176
1212 for (intptr_t i = 0; i < mat->InputCount(); i++) { 1177 for (intptr_t i = 0; i < mat->InputCount(); i++) {
1213 MaterializeObjectInstr* nested_mat = mat->InputAt(i)->definition()-> 1178 MaterializeObjectInstr* nested_mat =
1214 AsMaterializeObject(); 1179 mat->InputAt(i)->definition()->AsMaterializeObject();
1215 if (nested_mat != NULL) { 1180 if (nested_mat != NULL) {
1216 AddMaterialization(nested_mat); 1181 AddMaterialization(nested_mat);
1217 } 1182 }
1218 } 1183 }
1219 } 1184 }
1220 1185
1221 1186
1222 intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t dest_index) { 1187 intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t dest_index) {
1223 ASSERT(dest_index == kDartFrameFixedSize); 1188 ASSERT(dest_index == kDartFrameFixedSize);
1224 for (intptr_t i = 0; i < materializations_.length(); i++) { 1189 for (intptr_t i = 0; i < materializations_.length(); i++) {
(...skipping 21 matching lines...) Expand all
1246 return i; 1211 return i;
1247 } 1212 }
1248 } 1213 }
1249 return -1; 1214 return -1;
1250 } 1215 }
1251 1216
1252 1217
1253 static uint8_t* ZoneReAlloc(uint8_t* ptr, 1218 static uint8_t* ZoneReAlloc(uint8_t* ptr,
1254 intptr_t old_size, 1219 intptr_t old_size,
1255 intptr_t new_size) { 1220 intptr_t new_size) {
1256 return Thread::Current()->zone()->Realloc<uint8_t>( 1221 return Thread::Current()->zone()->Realloc<uint8_t>(ptr, old_size, new_size);
1257 ptr, old_size, new_size);
1258 } 1222 }
1259 1223
1260 1224
1261 RawTypedData* DeoptInfoBuilder::CreateDeoptInfo(const Array& deopt_table) { 1225 RawTypedData* DeoptInfoBuilder::CreateDeoptInfo(const Array& deopt_table) {
1262 intptr_t length = instructions_.length(); 1226 intptr_t length = instructions_.length();
1263 1227
1264 // Count the number of instructions that are a shared suffix of some deopt 1228 // Count the number of instructions that are a shared suffix of some deopt
1265 // info already written. 1229 // info already written.
1266 TrieNode* suffix = trie_root_; 1230 TrieNode* suffix = trie_root_;
1267 intptr_t suffix_length = 0; 1231 intptr_t suffix_length = 0;
(...skipping 28 matching lines...) Expand all
1296 } 1260 }
1297 1261
1298 // Write the unshared instructions and build their sub-tree. 1262 // Write the unshared instructions and build their sub-tree.
1299 TrieNode* node = use_suffix ? suffix : trie_root_; 1263 TrieNode* node = use_suffix ? suffix : trie_root_;
1300 const intptr_t write_count = use_suffix ? length - 1 : length; 1264 const intptr_t write_count = use_suffix ? length - 1 : length;
1301 for (intptr_t i = write_count - 1; i >= 0; --i) { 1265 for (intptr_t i = write_count - 1; i >= 0; --i) {
1302 DeoptInstr* instr = instructions_[i]; 1266 DeoptInstr* instr = instructions_[i];
1303 Writer::Write(&stream, instr->kind()); 1267 Writer::Write(&stream, instr->kind());
1304 Writer::Write(&stream, instr->source_index()); 1268 Writer::Write(&stream, instr->source_index());
1305 1269
1306 TrieNode* child = new(zone()) TrieNode(instr, current_info_number_); 1270 TrieNode* child = new (zone()) TrieNode(instr, current_info_number_);
1307 node->AddChild(child); 1271 node->AddChild(child);
1308 node = child; 1272 node = child;
1309 } 1273 }
1310 1274
1311 const TypedData& deopt_info = TypedData::Handle(zone(), TypedData::New( 1275 const TypedData& deopt_info = TypedData::Handle(
1312 kTypedDataUint8ArrayCid, stream.bytes_written(), Heap::kOld)); 1276 zone(), TypedData::New(kTypedDataUint8ArrayCid, stream.bytes_written(),
1277 Heap::kOld));
1313 { 1278 {
1314 NoSafepointScope no_safepoint; 1279 NoSafepointScope no_safepoint;
1315 memmove(deopt_info.DataAddr(0), 1280 memmove(deopt_info.DataAddr(0), stream.buffer(), stream.bytes_written());
1316 stream.buffer(),
1317 stream.bytes_written());
1318 } 1281 }
1319 1282
1320 ASSERT(DeoptInfo::VerifyDecompression( 1283 ASSERT(
1321 instructions_, deopt_table, deopt_info)); 1284 DeoptInfo::VerifyDecompression(instructions_, deopt_table, deopt_info));
1322 instructions_.Clear(); 1285 instructions_.Clear();
1323 materializations_.Clear(); 1286 materializations_.Clear();
1324 frame_start_ = -1; 1287 frame_start_ = -1;
1325 1288
1326 ++current_info_number_; 1289 ++current_info_number_;
1327 return deopt_info.raw(); 1290 return deopt_info.raw();
1328 } 1291 }
1329 1292
1330 1293
1331 intptr_t DeoptTable::SizeFor(intptr_t length) { 1294 intptr_t DeoptTable::SizeFor(intptr_t length) {
(...skipping 24 matching lines...) Expand all
1356 Smi* offset, 1319 Smi* offset,
1357 TypedData* info, 1320 TypedData* info,
1358 Smi* reason) { 1321 Smi* reason) {
1359 intptr_t i = index * kEntrySize; 1322 intptr_t i = index * kEntrySize;
1360 *offset ^= table.At(i); 1323 *offset ^= table.At(i);
1361 *info ^= table.At(i + 1); 1324 *info ^= table.At(i + 1);
1362 *reason ^= table.At(i + 2); 1325 *reason ^= table.At(i + 2);
1363 } 1326 }
1364 1327
1365 } // namespace dart 1328 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/deopt_instructions.h ('k') | runtime/vm/disassembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698