| 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/code_generator.h" | 5 #include "vm/code_generator.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
| 9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 } | 1285 } |
| 1286 arguments.SetReturn(Code::Handle(isolate, function.CurrentCode())); | 1286 arguments.SetReturn(Code::Handle(isolate, function.CurrentCode())); |
| 1287 } | 1287 } |
| 1288 | 1288 |
| 1289 | 1289 |
| 1290 // The caller must be a static call in a Dart frame, or an entry frame. | 1290 // The caller must be a static call in a Dart frame, or an entry frame. |
| 1291 // Patch static call to point to valid code's entry point. | 1291 // Patch static call to point to valid code's entry point. |
| 1292 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { | 1292 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { |
| 1293 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); | 1293 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); |
| 1294 StackFrame* frame = iterator.NextFrame(); | 1294 StackFrame* frame = iterator.NextFrame(); |
| 1295 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { | 1295 ASSERT(frame != NULL); |
| 1296 while (frame->IsStubFrame() || frame->IsExitFrame()) { |
| 1296 frame = iterator.NextFrame(); | 1297 frame = iterator.NextFrame(); |
| 1298 ASSERT(frame != NULL); |
| 1297 } | 1299 } |
| 1298 ASSERT(frame != NULL); | |
| 1299 if (frame->IsEntryFrame()) { | 1300 if (frame->IsEntryFrame()) { |
| 1300 // Since function's current code is always unpatched, the entry frame always | 1301 // Since function's current code is always unpatched, the entry frame always |
| 1301 // calls to unpatched code. | 1302 // calls to unpatched code. |
| 1302 UNREACHABLE(); | 1303 UNREACHABLE(); |
| 1303 } | 1304 } |
| 1304 ASSERT(frame->IsDartFrame()); | 1305 ASSERT(frame->IsDartFrame()); |
| 1305 const Code& caller_code = Code::Handle(isolate, frame->LookupDartCode()); | 1306 const Code& caller_code = Code::Handle(isolate, frame->LookupDartCode()); |
| 1306 ASSERT(caller_code.is_optimized()); | 1307 ASSERT(caller_code.is_optimized()); |
| 1307 const Function& target_function = Function::Handle( | 1308 const Function& target_function = Function::Handle( |
| 1308 isolate, caller_code.GetStaticCallTargetFunctionAt(frame->pc())); | 1309 isolate, caller_code.GetStaticCallTargetFunctionAt(frame->pc())); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1334 "target '%s' %#" Px " -> %#" Px "\n", | 1335 "target '%s' %#" Px " -> %#" Px "\n", |
| 1335 frame->pc(), | 1336 frame->pc(), |
| 1336 target_function.ToFullyQualifiedCString(), | 1337 target_function.ToFullyQualifiedCString(), |
| 1337 target_code.EntryPoint(), | 1338 target_code.EntryPoint(), |
| 1338 current_target_code.EntryPoint()); | 1339 current_target_code.EntryPoint()); |
| 1339 } | 1340 } |
| 1340 arguments.SetReturn(current_target_code); | 1341 arguments.SetReturn(current_target_code); |
| 1341 } | 1342 } |
| 1342 | 1343 |
| 1343 | 1344 |
| 1345 // The caller tried to allocate an instance via an invalidated allocation |
| 1346 // stub. |
| 1347 DEFINE_RUNTIME_ENTRY(FixAllocationStubTarget, 0) { |
| 1348 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); |
| 1349 StackFrame* frame = iterator.NextFrame(); |
| 1350 ASSERT(frame != NULL); |
| 1351 while (frame->IsStubFrame() || frame->IsExitFrame()) { |
| 1352 frame = iterator.NextFrame(); |
| 1353 ASSERT(frame != NULL); |
| 1354 } |
| 1355 if (frame->IsEntryFrame()) { |
| 1356 // There must be a valid Dart frame. |
| 1357 UNREACHABLE(); |
| 1358 } |
| 1359 ASSERT(frame->IsDartFrame()); |
| 1360 const Code& caller_code = Code::Handle(isolate, frame->LookupDartCode()); |
| 1361 ASSERT(!caller_code.IsNull()); |
| 1362 const uword target = |
| 1363 CodePatcher::GetStaticCallTargetAt(frame->pc(), caller_code); |
| 1364 const Code& stub = Code::Handle(isolate, Code::LookupCode(target)); |
| 1365 Class& alloc_class = Class::ZoneHandle(isolate); |
| 1366 alloc_class ^= stub.owner(); |
| 1367 Code& alloc_stub = Code::Handle(isolate, alloc_class.allocation_stub()); |
| 1368 if (alloc_stub.IsNull()) { |
| 1369 alloc_stub = isolate->stub_code()->GetAllocationStubForClass(alloc_class); |
| 1370 ASSERT(!CodePatcher::IsEntryPatched(alloc_stub)); |
| 1371 } |
| 1372 const Instructions& instrs = |
| 1373 Instructions::Handle(isolate, caller_code.instructions()); |
| 1374 { |
| 1375 WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size()); |
| 1376 CodePatcher::PatchStaticCallAt(frame->pc(), |
| 1377 caller_code, |
| 1378 alloc_stub.EntryPoint()); |
| 1379 } |
| 1380 if (FLAG_trace_patching) { |
| 1381 OS::PrintErr("FixAllocationStubTarget: caller %#" Px " " |
| 1382 " -> %#" Px "\n", |
| 1383 frame->pc(), |
| 1384 alloc_stub.EntryPoint()); |
| 1385 } |
| 1386 arguments.SetReturn(alloc_stub); |
| 1387 } |
| 1388 |
| 1389 |
| 1344 const char* DeoptReasonToCString(ICData::DeoptReasonId deopt_reason) { | 1390 const char* DeoptReasonToCString(ICData::DeoptReasonId deopt_reason) { |
| 1345 switch (deopt_reason) { | 1391 switch (deopt_reason) { |
| 1346 #define DEOPT_REASON_TO_TEXT(name) case ICData::kDeopt##name: return #name; | 1392 #define DEOPT_REASON_TO_TEXT(name) case ICData::kDeopt##name: return #name; |
| 1347 DEOPT_REASONS(DEOPT_REASON_TO_TEXT) | 1393 DEOPT_REASONS(DEOPT_REASON_TO_TEXT) |
| 1348 #undef DEOPT_REASON_TO_TEXT | 1394 #undef DEOPT_REASON_TO_TEXT |
| 1349 default: | 1395 default: |
| 1350 UNREACHABLE(); | 1396 UNREACHABLE(); |
| 1351 return ""; | 1397 return ""; |
| 1352 } | 1398 } |
| 1353 } | 1399 } |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1575 field.RecordStore(value); | 1621 field.RecordStore(value); |
| 1576 } | 1622 } |
| 1577 | 1623 |
| 1578 | 1624 |
| 1579 DEFINE_RUNTIME_ENTRY(InitStaticField, 1) { | 1625 DEFINE_RUNTIME_ENTRY(InitStaticField, 1) { |
| 1580 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1626 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
| 1581 field.EvaluateInitializer(); | 1627 field.EvaluateInitializer(); |
| 1582 } | 1628 } |
| 1583 | 1629 |
| 1584 } // namespace dart | 1630 } // namespace dart |
| OLD | NEW |