mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:27:17 +00:00
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:
parent
bac82e2592
commit
18faa55764
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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("]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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())),
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue