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

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

Issue 70183010: Fixes a couple problems with GC of unoptimized code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/block_scheduler.cc ('k') | runtime/vm/code_patcher.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/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/bigint_operations.h" 9 #include "vm/bigint_operations.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
(...skipping 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 Dart_IsolateInterruptCallback callback = isolate->VmStatsCallback(); 1334 Dart_IsolateInterruptCallback callback = isolate->VmStatsCallback();
1335 if (callback) { 1335 if (callback) {
1336 (*callback)(); 1336 (*callback)();
1337 } 1337 }
1338 } 1338 }
1339 1339
1340 if (FLAG_use_osr && (interrupt_bits == 0)) { 1340 if (FLAG_use_osr && (interrupt_bits == 0)) {
1341 DartFrameIterator iterator; 1341 DartFrameIterator iterator;
1342 StackFrame* frame = iterator.NextFrame(); 1342 StackFrame* frame = iterator.NextFrame();
1343 ASSERT(frame != NULL); 1343 ASSERT(frame != NULL);
1344 const Function& function = Function::Handle(frame->LookupDartFunction()); 1344 const Code& code = Code::ZoneHandle(frame->LookupDartCode());
1345 ASSERT(!code.IsNull());
1346 const Function& function = Function::Handle(code.function());
1345 ASSERT(!function.IsNull()); 1347 ASSERT(!function.IsNull());
1346 if (!CanOptimizeFunction(function, isolate)) return; 1348 // Since the code is referenced from the frame and the ZoneHandle,
1349 // it cannot have been removed from the function.
1350 ASSERT(function.HasCode());
1351 if (!CanOptimizeFunction(function, isolate)) {
1352 return;
1353 }
1347 intptr_t osr_id = 1354 intptr_t osr_id =
1348 Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc()); 1355 Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc());
1349 if (FLAG_trace_osr) { 1356 if (FLAG_trace_osr) {
1350 OS::Print("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n", 1357 OS::Print("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n",
1351 function.ToFullyQualifiedCString(), 1358 function.ToFullyQualifiedCString(),
1352 osr_id, 1359 osr_id,
1353 function.usage_counter()); 1360 function.usage_counter());
1354 } 1361 }
1355 1362
1356 const Code& original_code = Code::Handle(function.CurrentCode()); 1363 const Code& original_code = Code::Handle(function.CurrentCode());
1364 // Since the code is referenced from the frame and the ZoneHandle,
1365 // it cannot have been removed from the function.
1366 ASSERT(!original_code.IsNull());
1357 const Error& error = 1367 const Error& error =
1358 Error::Handle(Compiler::CompileOptimizedFunction(function, osr_id)); 1368 Error::Handle(Compiler::CompileOptimizedFunction(function, osr_id));
1359 if (!error.IsNull()) Exceptions::PropagateError(error); 1369 if (!error.IsNull()) {
1370 Exceptions::PropagateError(error);
1371 }
1360 1372
1361 const Code& optimized_code = Code::Handle(function.CurrentCode()); 1373 const Code& optimized_code = Code::Handle(function.CurrentCode());
1362 // The current code will not be changed in the case that the compiler 1374 // The current code will not be changed in the case that the compiler
1363 // bailed out during OSR compilation. 1375 // bailed out during OSR compilation.
1364 if (optimized_code.raw() != original_code.raw()) { 1376 if (optimized_code.raw() != original_code.raw()) {
1365 // The OSR code does not work for calling the function, so restore the 1377 // The OSR code does not work for calling the function, so restore the
1366 // unoptimized code. Patch the stack frame to return into the OSR 1378 // unoptimized code. Patch the stack frame to return into the OSR
1367 // code. 1379 // code.
1368 uword optimized_entry = 1380 uword optimized_entry =
1369 Instructions::Handle(optimized_code.instructions()).EntryPoint(); 1381 Instructions::Handle(optimized_code.instructions()).EntryPoint();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 if (frame->IsEntryFrame()) { 1438 if (frame->IsEntryFrame()) {
1427 // Since function's current code is always unpatched, the entry frame always 1439 // Since function's current code is always unpatched, the entry frame always
1428 // calls to unpatched code. 1440 // calls to unpatched code.
1429 UNREACHABLE(); 1441 UNREACHABLE();
1430 } 1442 }
1431 ASSERT(frame->IsDartFrame()); 1443 ASSERT(frame->IsDartFrame());
1432 const Code& caller_code = Code::Handle(frame->LookupDartCode()); 1444 const Code& caller_code = Code::Handle(frame->LookupDartCode());
1433 ASSERT(caller_code.is_optimized()); 1445 ASSERT(caller_code.is_optimized());
1434 const Function& target_function = Function::Handle( 1446 const Function& target_function = Function::Handle(
1435 caller_code.GetStaticCallTargetFunctionAt(frame->pc())); 1447 caller_code.GetStaticCallTargetFunctionAt(frame->pc()));
1448 const Code& target_code = Code::Handle(
1449 caller_code.GetStaticCallTargetCodeAt(frame->pc()));
1450 ASSERT(!target_code.IsNull());
1451 // Since there was a reference to the target_code in the caller_code, it is
1452 // not possible for the target_function's code to be disconnected.
1453 ASSERT(target_function.HasCode());
1454 ASSERT(target_function.raw() == target_code.function());
1436 1455
1437 // Check whether the code object has been detached from the target function. 1456 const Code& current_target_code = Code::Handle(target_function.CurrentCode());
1438 // If it has been detached, reattach it. 1457 CodePatcher::PatchStaticCallAt(frame->pc(), caller_code,
1439 Code& target_code = Code::Handle(); 1458 current_target_code.EntryPoint());
1440 if (target_function.HasCode()) { 1459 caller_code.SetStaticCallTargetCodeAt(frame->pc(), current_target_code);
1441 target_code ^= target_function.CurrentCode();
1442 CodePatcher::PatchStaticCallAt(frame->pc(), caller_code,
1443 target_code.EntryPoint());
1444 caller_code.SetStaticCallTargetCodeAt(frame->pc(), target_code);
1445 } else {
1446 ASSERT(target_function.unoptimized_code() == Code::null());
1447 target_code ^= caller_code.GetStaticCallTargetCodeAt(frame->pc());
1448 ASSERT(!target_code.IsNull());
1449 ASSERT(!target_code.is_optimized());
1450 target_function.ReattachCode(target_code);
1451 }
1452 if (FLAG_trace_patching) { 1460 if (FLAG_trace_patching) {
1453 OS::PrintErr("FixCallersTarget: patching from %#" Px " to '%s' %#" Px "\n", 1461 OS::PrintErr("FixCallersTarget: patching from %#" Px " to '%s' %#" Px "\n",
1454 frame->pc(), 1462 frame->pc(),
1455 Function::Handle(target_code.function()).ToFullyQualifiedCString(), 1463 target_function.ToFullyQualifiedCString(),
1456 target_code.EntryPoint()); 1464 current_target_code.EntryPoint());
1457 } 1465 }
1458 arguments.SetReturn(target_code); 1466 arguments.SetReturn(current_target_code);
1459 ASSERT(target_function.HasCode());
1460 } 1467 }
1461 1468
1462 1469
1463 const char* DeoptReasonToText(intptr_t deopt_id) { 1470 const char* DeoptReasonToText(intptr_t deopt_id) {
1464 switch (deopt_id) { 1471 switch (deopt_id) {
1465 #define DEOPT_REASON_ID_TO_TEXT(name) case kDeopt##name: return #name; 1472 #define DEOPT_REASON_ID_TO_TEXT(name) case kDeopt##name: return #name;
1466 DEOPT_REASONS(DEOPT_REASON_ID_TO_TEXT) 1473 DEOPT_REASONS(DEOPT_REASON_ID_TO_TEXT)
1467 #undef DEOPT_REASON_ID_TO_TEXT 1474 #undef DEOPT_REASON_ID_TO_TEXT
1468 default: 1475 default:
1469 UNREACHABLE(); 1476 UNREACHABLE();
1470 return ""; 1477 return "";
1471 } 1478 }
1472 } 1479 }
1473 1480
1474 1481
1475 void DeoptimizeAt(const Code& optimized_code, uword pc) { 1482 void DeoptimizeAt(const Code& optimized_code, uword pc) {
1476 ASSERT(optimized_code.is_optimized()); 1483 ASSERT(optimized_code.is_optimized());
1477 intptr_t deopt_reason = kDeoptUnknown; 1484 intptr_t deopt_reason = kDeoptUnknown;
1478 const DeoptInfo& deopt_info = 1485 const DeoptInfo& deopt_info =
1479 DeoptInfo::Handle(optimized_code.GetDeoptInfoAtPc(pc, &deopt_reason)); 1486 DeoptInfo::Handle(optimized_code.GetDeoptInfoAtPc(pc, &deopt_reason));
1480 ASSERT(!deopt_info.IsNull()); 1487 ASSERT(!deopt_info.IsNull());
1481 const Function& function = Function::Handle(optimized_code.function()); 1488 const Function& function = Function::Handle(optimized_code.function());
1482 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); 1489 const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
1483 ASSERT(!unoptimized_code.IsNull()); 1490 ASSERT(!unoptimized_code.IsNull());
1484 // The switch to unoptimized code may have already occured. 1491 // The switch to unoptimized code may have already occurred.
1485 if (function.HasOptimizedCode()) { 1492 if (function.HasOptimizedCode()) {
1486 function.SwitchToUnoptimizedCode(); 1493 function.SwitchToUnoptimizedCode();
1487 } 1494 }
1488 // Patch call site (lazy deoptimization is quite rare, patching it twice 1495 // Patch call site (lazy deoptimization is quite rare, patching it twice
1489 // is not a performance issue). 1496 // is not a performance issue).
1490 uword lazy_deopt_jump = optimized_code.GetLazyDeoptPc(); 1497 uword lazy_deopt_jump = optimized_code.GetLazyDeoptPc();
1491 ASSERT(lazy_deopt_jump != 0); 1498 ASSERT(lazy_deopt_jump != 0);
1492 CodePatcher::InsertCallAt(pc, lazy_deopt_jump); 1499 CodePatcher::InsertCallAt(pc, lazy_deopt_jump);
1493 // Mark code as dead (do not GC its embedded objects). 1500 // Mark code as dead (do not GC its embedded objects).
1494 optimized_code.set_is_alive(false); 1501 optimized_code.set_is_alive(false);
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 // of the given value. 1707 // of the given value.
1701 // Arg0: Field object; 1708 // Arg0: Field object;
1702 // Arg1: Value that is being stored. 1709 // Arg1: Value that is being stored.
1703 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { 1710 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) {
1704 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); 1711 const Field& field = Field::CheckedHandle(arguments.ArgAt(0));
1705 const Object& value = Object::Handle(arguments.ArgAt(1)); 1712 const Object& value = Object::Handle(arguments.ArgAt(1));
1706 field.UpdateGuardedCidAndLength(value); 1713 field.UpdateGuardedCidAndLength(value);
1707 } 1714 }
1708 1715
1709 } // namespace dart 1716 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/block_scheduler.cc ('k') | runtime/vm/code_patcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698