Fix lazy deoptimization from deferred code.

Insert enough padding to ensure enough space for when lazy deoptimization occurs
from the last deferred code object.

Also, speed up ia32 disassembler to avoid tests timing out.

BUG=

TBR=rmacnak@google.com,

Review URL: https://codereview.chromium.org//1355953002 .
This commit is contained in:
Florian Schneider 2015-09-19 18:00:36 +02:00
parent bac82e2592
commit 18faa55764
11 changed files with 49 additions and 16 deletions

View file

@ -104,7 +104,8 @@ class FindAddrVisitor : public FindObjectVisitor {
bool Disassembler::CanFindOldObject(uword addr) {
FindAddrVisitor visitor(addr);
NoSafepointScope no_safepoint;
return Isolate::Current()->heap()->FindOldObject(&visitor) != Object::null();
return Dart::vm_isolate()->heap()->FindOldObject(&visitor) != Object::null()
|| Isolate::Current()->heap()->FindOldObject(&visitor) != Object::null();
}

View file

@ -494,6 +494,7 @@ void X86Decoder::PrintAddress(uword addr) {
reinterpret_cast<RawObject*>(addr)->IsWellFormed() &&
reinterpret_cast<RawObject*>(addr)->IsOldObject() &&
!Isolate::Current()->heap()->CodeContains(addr) &&
!Dart::vm_isolate()->heap()->CodeContains(addr) &&
Disassembler::CanFindOldObject(addr)) {
NoSafepointScope no_safepoint;
const Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr));
@ -524,16 +525,6 @@ void X86Decoder::PrintAddress(uword addr) {
Print(" [stub: ");
Print(name_of_stub);
Print("]");
} else {
// Print only if jumping to entry point.
const Code& code = Code::Handle(Code::LookupCode(addr));
if (!code.IsNull() && (code.EntryPoint() == addr)) {
const String& name = String::Handle(code.PrettyName());
const char* name_c = name.ToCString();
Print(" [");
Print(name_c);
Print("]");
}
}
}
}

View file

@ -13,6 +13,7 @@
#include "vm/dart_entry.h"
#include "vm/deopt_instructions.h"
#include "vm/il_printer.h"
#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@ -1109,6 +1110,13 @@ void FlowGraphCompiler::CompileGraph() {
GenerateDeferredCode();
if (is_optimizing()) {
// Leave enough space for patching in case of lazy deoptimization from
// deferred code.
for (intptr_t i = 0;
i < CallPattern::DeoptCallPatternLengthInInstructions();
++i) {
__ nop();
}
lazy_deopt_pc_offset_ = assembler()->CodeSize();
__ Branch(*StubCode::DeoptimizeLazy_entry());
}

View file

@ -13,6 +13,7 @@
#include "vm/dart_entry.h"
#include "vm/deopt_instructions.h"
#include "vm/il_printer.h"
#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@ -1110,6 +1111,13 @@ void FlowGraphCompiler::CompileGraph() {
GenerateDeferredCode();
if (is_optimizing()) {
// Leave enough space for patching in case of lazy deoptimization from
// deferred code.
for (intptr_t i = 0;
i < CallPattern::kDeoptCallLengthInInstructions;
++i) {
__ orr(R0, ZR, Operand(R0)); // nop
}
lazy_deopt_pc_offset_ = assembler()->CodeSize();
__ BranchPatchable(*StubCode::DeoptimizeLazy_entry());
}

View file

@ -15,6 +15,7 @@
#include "vm/deopt_instructions.h"
#include "vm/flow_graph_builder.h"
#include "vm/il_printer.h"
#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@ -1128,6 +1129,9 @@ void FlowGraphCompiler::CompileGraph() {
GenerateDeferredCode();
if (is_optimizing()) {
// Leave enough space for patching in case of lazy deoptimization from
// deferred code.
__ nop(CallPattern::pattern_length_in_bytes());
lazy_deopt_pc_offset_ = assembler()->CodeSize();
__ Jmp(*StubCode::DeoptimizeLazy_entry());
}

View file

@ -12,6 +12,7 @@
#include "vm/dart_entry.h"
#include "vm/deopt_instructions.h"
#include "vm/il_printer.h"
#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@ -1126,6 +1127,13 @@ void FlowGraphCompiler::CompileGraph() {
GenerateDeferredCode();
if (is_optimizing()) {
// Leave enough space for patching in case of lazy deoptimization from
// deferred code.
for (intptr_t i = 0;
i < CallPattern::kDeoptCallLengthInInstructions;
++i) {
__ nop();
}
lazy_deopt_pc_offset_ = assembler()->CodeSize();
__ Branch(*StubCode::DeoptimizeLazy_entry());
}

View file

@ -12,6 +12,7 @@
#include "vm/dart_entry.h"
#include "vm/deopt_instructions.h"
#include "vm/il_printer.h"
#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@ -1128,6 +1129,9 @@ void FlowGraphCompiler::CompileGraph() {
// at entry point.
if (is_optimizing()) {
// Leave enough space for patching in case of lazy deoptimization from
// deferred code.
__ nop(ShortCallPattern::pattern_length_in_bytes());
lazy_deopt_pc_offset_ = assembler()->CodeSize();
__ Jmp(*StubCode::DeoptimizeLazy_entry(), PP);
}

View file

@ -32,16 +32,20 @@ CallPattern::CallPattern(uword pc, const Code& code)
}
int CallPattern::DeoptCallPatternLengthInBytes() {
int CallPattern::DeoptCallPatternLengthInInstructions() {
const ARMVersion version = TargetCPUFeatures::arm_version();
if ((version == ARMv5TE) || (version == ARMv6)) {
return 5 * Instr::kInstrSize;
return 5;
} else {
ASSERT(version == ARMv7);
return 3 * Instr::kInstrSize;
return 3;
}
}
int CallPattern::DeoptCallPatternLengthInBytes() {
return DeoptCallPatternLengthInInstructions() * Instr::kInstrSize;
}
NativeCallPattern::NativeCallPattern(uword pc, const Code& code)
: object_pool_(ObjectPool::Handle(code.GetObjectPool())),

View file

@ -60,6 +60,7 @@ class CallPattern : public ValueObject {
// This constant length is only valid for inserted call patterns used for
// lazy deoptimization. Regular call pattern may vary in length.
static int DeoptCallPatternLengthInBytes();
static int DeoptCallPatternLengthInInstructions();
static void InsertDeoptCallAt(uword pc, uword target_address);

View file

@ -66,7 +66,9 @@ class CallPattern : public ValueObject {
// This constant length is only valid for inserted call patterns used for
// lazy deoptimization. Regular call pattern may vary in length.
static const int kDeoptCallLengthInBytes = 5 * Instr::kInstrSize;
static const int kDeoptCallLengthInInstructions = 5;
static const int kDeoptCallLengthInBytes =
kDeoptCallLengthInInstructions * Instr::kInstrSize;
static void InsertDeoptCallAt(uword pc, uword target_address);

View file

@ -57,7 +57,9 @@ class CallPattern : public ValueObject {
RawCode* TargetCode() const;
void SetTargetCode(const Code& target) const;
static const int kDeoptCallLengthInBytes = 4 * Instr::kInstrSize;
static const int kDeoptCallLengthInInstructions = 4;
static const int kDeoptCallLengthInBytes =
kDeoptCallLengthInInstructions * Instr::kInstrSize;
static void InsertDeoptCallAt(uword pc, uword target_address);