OLD | NEW |
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/intermediate_language.h" | 10 #include "vm/intermediate_language.h" |
11 #include "vm/locations.h" | 11 #include "vm/locations.h" |
12 #include "vm/parser.h" | 12 #include "vm/parser.h" |
13 #include "vm/stack_frame.h" | 13 #include "vm/stack_frame.h" |
14 #include "vm/thread.h" | 14 #include "vm/thread.h" |
| 15 #include "vm/timeline.h" |
15 | 16 |
16 namespace dart { | 17 namespace dart { |
17 | 18 |
18 DEFINE_FLAG(bool, compress_deopt_info, true, | 19 DEFINE_FLAG(bool, compress_deopt_info, true, |
19 "Compress the size of the deoptimization info for optimized code."); | 20 "Compress the size of the deoptimization info for optimized code."); |
20 DECLARE_FLAG(bool, trace_deoptimization); | 21 DECLARE_FLAG(bool, trace_deoptimization); |
21 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 22 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
22 | 23 |
23 | 24 |
24 DeoptContext::DeoptContext(const StackFrame* frame, | 25 DeoptContext::DeoptContext(const StackFrame* frame, |
25 const Code& code, | 26 const Code& code, |
26 DestFrameOptions dest_options, | 27 DestFrameOptions dest_options, |
27 fpu_register_t* fpu_registers, | 28 fpu_register_t* fpu_registers, |
28 intptr_t* cpu_registers) | 29 intptr_t* cpu_registers) |
29 : code_(code.raw()), | 30 : code_(code.raw()), |
30 object_pool_(code.GetObjectPool()), | 31 object_pool_(code.GetObjectPool()), |
31 deopt_info_(TypedData::null()), | 32 deopt_info_(TypedData::null()), |
32 dest_frame_is_allocated_(false), | 33 dest_frame_is_allocated_(false), |
33 dest_frame_(NULL), | 34 dest_frame_(NULL), |
34 dest_frame_size_(0), | 35 dest_frame_size_(0), |
35 source_frame_is_allocated_(false), | 36 source_frame_is_allocated_(false), |
36 source_frame_(NULL), | 37 source_frame_(NULL), |
37 source_frame_size_(0), | 38 source_frame_size_(0), |
38 cpu_registers_(cpu_registers), | 39 cpu_registers_(cpu_registers), |
39 fpu_registers_(fpu_registers), | 40 fpu_registers_(fpu_registers), |
40 num_args_(0), | 41 num_args_(0), |
41 deopt_reason_(ICData::kDeoptUnknown), | 42 deopt_reason_(ICData::kDeoptUnknown), |
42 deopt_flags_(0), | 43 deopt_flags_(0), |
43 thread_(Thread::Current()), | 44 thread_(Thread::Current()), |
| 45 timeline_event_(NULL), |
44 deferred_slots_(NULL), | 46 deferred_slots_(NULL), |
45 deferred_objects_count_(0), | 47 deferred_objects_count_(0), |
46 deferred_objects_(NULL) { | 48 deferred_objects_(NULL) { |
47 const TypedData& deopt_info = TypedData::Handle( | 49 const TypedData& deopt_info = TypedData::Handle( |
48 code.GetDeoptInfoAtPc(frame->pc(), &deopt_reason_, &deopt_flags_)); | 50 code.GetDeoptInfoAtPc(frame->pc(), &deopt_reason_, &deopt_flags_)); |
49 ASSERT(!deopt_info.IsNull()); | 51 ASSERT(!deopt_info.IsNull()); |
50 deopt_info_ = deopt_info.raw(); | 52 deopt_info_ = deopt_info.raw(); |
51 | 53 |
52 const Function& function = Function::Handle(code.function()); | 54 const Function& function = Function::Handle(code.function()); |
53 | 55 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 | 87 |
86 if (dest_options == kDestIsAllocated) { | 88 if (dest_options == kDestIsAllocated) { |
87 dest_frame_ = new intptr_t[dest_frame_size_]; | 89 dest_frame_ = new intptr_t[dest_frame_size_]; |
88 ASSERT(source_frame_ != NULL); | 90 ASSERT(source_frame_ != NULL); |
89 for (intptr_t i = 0; i < dest_frame_size_; i++) { | 91 for (intptr_t i = 0; i < dest_frame_size_; i++) { |
90 dest_frame_[i] = 0; | 92 dest_frame_[i] = 0; |
91 } | 93 } |
92 dest_frame_is_allocated_ = true; | 94 dest_frame_is_allocated_ = true; |
93 } | 95 } |
94 | 96 |
| 97 if (dest_options != kDestIsAllocated) { |
| 98 // kDestIsAllocated is used by the debugger to generate a stack trace |
| 99 // and does not signal a real deopt. |
| 100 Isolate* isolate = Isolate::Current(); |
| 101 TimelineStream* compiler_stream = isolate->GetCompilerStream(); |
| 102 ASSERT(compiler_stream != NULL); |
| 103 timeline_event_ = compiler_stream->RecordEvent(); |
| 104 if (timeline_event_ != NULL) { |
| 105 timeline_event_->DurationBegin(compiler_stream, "Deoptimize"); |
| 106 timeline_event_->SetNumArguments(3); |
| 107 } |
| 108 } |
| 109 |
95 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { | 110 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { |
96 OS::PrintErr( | 111 OS::PrintErr( |
97 "Deoptimizing (reason %d '%s') at pc %#" Px " '%s' (count %d)\n", | 112 "Deoptimizing (reason %d '%s') at pc %#" Px " '%s' (count %d)\n", |
98 deopt_reason(), | 113 deopt_reason(), |
99 DeoptReasonToCString(deopt_reason()), | 114 DeoptReasonToCString(deopt_reason()), |
100 frame->pc(), | 115 frame->pc(), |
101 function.ToFullyQualifiedCString(), | 116 function.ToFullyQualifiedCString(), |
102 function.deoptimization_counter()); | 117 function.deoptimization_counter()); |
103 } | 118 } |
104 } | 119 } |
(...skipping 14 matching lines...) Expand all Loading... |
119 } | 134 } |
120 dest_frame_ = NULL; | 135 dest_frame_ = NULL; |
121 | 136 |
122 // Delete all deferred objects. | 137 // Delete all deferred objects. |
123 for (intptr_t i = 0; i < deferred_objects_count_; i++) { | 138 for (intptr_t i = 0; i < deferred_objects_count_; i++) { |
124 delete deferred_objects_[i]; | 139 delete deferred_objects_[i]; |
125 } | 140 } |
126 delete[] deferred_objects_; | 141 delete[] deferred_objects_; |
127 deferred_objects_ = NULL; | 142 deferred_objects_ = NULL; |
128 deferred_objects_count_ = 0; | 143 deferred_objects_count_ = 0; |
| 144 if (timeline_event_ != NULL) { |
| 145 const Code& code = Code::Handle(zone(), code_); |
| 146 const Function& function = Function::Handle(zone(), code.function()); |
| 147 timeline_event_->CopyArgument( |
| 148 0, |
| 149 "function", |
| 150 const_cast<char*>(function.QualifiedUserVisibleNameCString())); |
| 151 timeline_event_->CopyArgument( |
| 152 1, |
| 153 "reason", |
| 154 const_cast<char*>(DeoptReasonToCString(deopt_reason()))); |
| 155 timeline_event_->FormatArgument( |
| 156 2, |
| 157 "deoptimizationCount", |
| 158 "%d", |
| 159 function.deoptimization_counter()); |
| 160 timeline_event_->DurationEnd(); |
| 161 } |
129 } | 162 } |
130 | 163 |
131 | 164 |
132 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 165 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
133 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_)); | 166 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_)); |
134 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_)); | 167 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_)); |
135 | 168 |
136 // Visit any object pointers on the destination stack. | 169 // Visit any object pointers on the destination stack. |
137 if (dest_frame_is_allocated_) { | 170 if (dest_frame_is_allocated_) { |
138 for (intptr_t i = 0; i < dest_frame_size_; i++) { | 171 for (intptr_t i = 0; i < dest_frame_size_; i++) { |
(...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1260 Smi* offset, | 1293 Smi* offset, |
1261 TypedData* info, | 1294 TypedData* info, |
1262 Smi* reason) { | 1295 Smi* reason) { |
1263 intptr_t i = index * kEntrySize; | 1296 intptr_t i = index * kEntrySize; |
1264 *offset ^= table.At(i); | 1297 *offset ^= table.At(i); |
1265 *info ^= table.At(i + 1); | 1298 *info ^= table.At(i + 1); |
1266 *reason ^= table.At(i + 2); | 1299 *reason ^= table.At(i + 2); |
1267 } | 1300 } |
1268 | 1301 |
1269 } // namespace dart | 1302 } // namespace dart |
OLD | NEW |