Chromium Code Reviews| 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/deferred_objects.h" | 5 #include "vm/deferred_objects.h" |
| 6 | 6 |
| 7 #include "vm/code_patcher.h" | |
| 8 #include "vm/compiler.h" | |
| 7 #include "vm/deopt_instructions.h" | 9 #include "vm/deopt_instructions.h" |
| 8 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| 9 #include "vm/object.h" | 11 #include "vm/object.h" |
| 10 | 12 |
| 11 namespace dart { | 13 namespace dart { |
| 12 | 14 |
| 13 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 15 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
| 16 DECLARE_FLAG(bool, trace_deoptimization); | |
|
srdjan
2015/04/02 17:43:40
Reorder alphabetically.
Florian Schneider
2015/04/07 09:07:57
Done.
| |
| 14 | 17 |
| 15 | 18 |
| 16 void DeferredDouble::Materialize(DeoptContext* deopt_context) { | 19 void DeferredDouble::Materialize(DeoptContext* deopt_context) { |
| 17 RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot()); | 20 RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot()); |
| 18 *double_slot = Double::New(value()); | 21 *double_slot = Double::New(value()); |
| 19 | 22 |
| 20 if (FLAG_trace_deoptimization_verbose) { | 23 if (FLAG_trace_deoptimization_verbose) { |
| 21 OS::PrintErr("materializing double at %" Px ": %g\n", | 24 OS::PrintErr("materializing double at %" Px ": %g\n", |
| 22 reinterpret_cast<uword>(slot()), value()); | 25 reinterpret_cast<uword>(slot()), value()); |
| 23 } | 26 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 if (FLAG_trace_deoptimization_verbose) { | 93 if (FLAG_trace_deoptimization_verbose) { |
| 91 const Class& cls = Class::Handle(Isolate::Current()->class_table()->At( | 94 const Class& cls = Class::Handle(Isolate::Current()->class_table()->At( |
| 92 Object::Handle(obj->object()).GetClassId())); | 95 Object::Handle(obj->object()).GetClassId())); |
| 93 OS::PrintErr("writing instance of class %s ref at %" Px ".\n", | 96 OS::PrintErr("writing instance of class %s ref at %" Px ".\n", |
| 94 cls.ToCString(), | 97 cls.ToCString(), |
| 95 reinterpret_cast<uword>(slot())); | 98 reinterpret_cast<uword>(slot())); |
| 96 } | 99 } |
| 97 } | 100 } |
| 98 | 101 |
| 99 | 102 |
| 103 void DeferredRetAddr::Materialize(DeoptContext* deopt_context) { | |
| 104 Function& function = Function::Handle(deopt_context->zone()); | |
| 105 function ^= deopt_context->ObjectAt(index_); | |
| 106 Compiler::EnsureUnoptimizedCode(deopt_context->thread(), function); | |
| 107 const Code& code = | |
| 108 Code::Handle(deopt_context->zone(), function.unoptimized_code()); | |
| 109 // Check that deopt_id exists. | |
| 110 // TODO(vegorov): verify after deoptimization targets as well. | |
| 111 #ifdef DEBUG | |
| 112 ASSERT(Isolate::IsDeoptAfter(deopt_id_) || | |
| 113 (code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kDeopt) != 0)); | |
| 114 #endif | |
| 115 | |
| 116 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_, | |
| 117 RawPcDescriptors::kDeopt); | |
| 118 ASSERT(continue_at_pc != 0); | |
| 119 uword* dest_addr = reinterpret_cast<uword*>(slot()); | |
| 120 *dest_addr = continue_at_pc; | |
| 121 | |
| 122 if (FLAG_trace_deoptimization_verbose) { | |
| 123 OS::PrintErr("materializing return addr at 0x%" Px ": 0x%" Px "\n", | |
| 124 reinterpret_cast<uword>(slot()), continue_at_pc); | |
| 125 } | |
| 126 | |
| 127 uword pc = code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kIcCall); | |
| 128 if (pc != 0) { | |
| 129 // If the deoptimization happened at an IC call, update the IC data | |
| 130 // to avoid repeated deoptimization at the same site next time around. | |
| 131 ICData& ic_data = ICData::Handle(); | |
| 132 CodePatcher::GetInstanceCallAt(pc, code, &ic_data); | |
| 133 if (!ic_data.IsNull()) { | |
| 134 ic_data.AddDeoptReason(deopt_context->deopt_reason()); | |
| 135 } | |
| 136 } else { | |
| 137 if (deopt_context->HasDeoptFlag(ICData::kHoisted)) { | |
| 138 // Prevent excessive deoptimization. | |
| 139 function.set_allows_hoisting_check_class(false); | |
| 140 } | |
| 141 | |
| 142 if (deopt_context->HasDeoptFlag(ICData::kGeneralized)) { | |
| 143 function.set_allows_bounds_check_generalization(false); | |
| 144 } | |
| 145 } | |
| 146 } | |
| 147 | |
| 148 | |
| 149 void DeferredPcMarker::Materialize(DeoptContext* deopt_context) { | |
| 150 uword* dest_addr = reinterpret_cast<uword*>(slot()); | |
| 151 Function& function = Function::Handle(deopt_context->zone()); | |
| 152 function ^= deopt_context->ObjectAt(index_); | |
| 153 if (function.IsNull()) { | |
| 154 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0. | |
| 155 *dest_addr = 0; | |
| 156 return; | |
| 157 } | |
| 158 Compiler::EnsureUnoptimizedCode(deopt_context->thread(), function); | |
| 159 const Code& code = | |
| 160 Code::Handle(deopt_context->zone(), function.unoptimized_code()); | |
| 161 ASSERT(!code.IsNull()); | |
| 162 ASSERT(function.HasCode()); | |
| 163 const intptr_t pc_marker = | |
| 164 code.EntryPoint() + Assembler::EntryPointToPcMarkerOffset(); | |
| 165 *dest_addr = pc_marker; | |
| 166 | |
| 167 if (FLAG_trace_deoptimization_verbose) { | |
| 168 OS::PrintErr("materializing pc marker at 0x%" Px ": %s, %s\n", | |
| 169 reinterpret_cast<uword>(slot()), code.ToCString(), | |
| 170 function.ToCString()); | |
| 171 } | |
| 172 | |
| 173 // Increment the deoptimization counter. This effectively increments each | |
| 174 // function occurring in the optimized frame. | |
| 175 function.set_deoptimization_counter(function.deoptimization_counter() + 1); | |
| 176 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { | |
| 177 OS::PrintErr("Deoptimizing %s (count %d)\n", | |
| 178 function.ToFullyQualifiedCString(), | |
| 179 function.deoptimization_counter()); | |
| 180 } | |
| 181 // Clear invocation counter so that hopefully the function gets reoptimized | |
| 182 // only after more feedback has been collected. | |
| 183 function.set_usage_counter(0); | |
| 184 if (function.HasOptimizedCode()) { | |
| 185 function.SwitchToUnoptimizedCode(); | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 | |
| 190 void DeferredPp::Materialize(DeoptContext* deopt_context) { | |
| 191 Function& function = Function::Handle(deopt_context->zone()); | |
| 192 function ^= deopt_context->ObjectAt(index_); | |
| 193 ASSERT(!function.IsNull()); | |
| 194 const Code& code = | |
| 195 Code::Handle(deopt_context->zone(), function.unoptimized_code()); | |
|
Ivan Posva
2015/04/02 17:14:00
Please add "Compiler::EnsureUnoptimizedCode(deopt_
Florian Schneider
2015/04/07 09:07:57
Good point. Done.
| |
| 196 ASSERT(!code.IsNull()); | |
| 197 ASSERT(code.ObjectPool() != Object::null()); | |
| 198 *slot() = code.ObjectPool(); | |
| 199 | |
| 200 if (FLAG_trace_deoptimization_verbose) { | |
| 201 OS::PrintErr("materializing pp at 0x%" Px ": 0x%" Px "\n", | |
| 202 reinterpret_cast<uword>(slot()), | |
| 203 reinterpret_cast<uword>(code.ObjectPool())); | |
| 204 } | |
| 205 } | |
| 206 | |
| 207 | |
| 100 RawObject* DeferredObject::object() { | 208 RawObject* DeferredObject::object() { |
| 101 if (object_ == NULL) { | 209 if (object_ == NULL) { |
| 102 Create(); | 210 Create(); |
| 103 } | 211 } |
| 104 return object_->raw(); | 212 return object_->raw(); |
| 105 } | 213 } |
| 106 | 214 |
| 107 | 215 |
| 108 void DeferredObject::Create() { | 216 void DeferredObject::Create() { |
| 109 if (object_ != NULL) { | 217 if (object_ != NULL) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 OS::PrintErr(" null Field @ offset(%" Pd ") <- %s\n", | 315 OS::PrintErr(" null Field @ offset(%" Pd ") <- %s\n", |
| 208 offset.Value(), | 316 offset.Value(), |
| 209 value.ToCString()); | 317 value.ToCString()); |
| 210 } | 318 } |
| 211 } | 319 } |
| 212 } | 320 } |
| 213 } | 321 } |
| 214 } | 322 } |
| 215 | 323 |
| 216 } // namespace dart | 324 } // namespace dart |
| OLD | NEW |