Revert "Replacing TrySync with Metadata"
This reverts commit cf08eebc71.
TBR=vegorov@google.com
Review-Url: https://codereview.chromium.org/2739663002 .
This commit is contained in:
@@ -1566,11 +1566,6 @@ class CodeSerializationCluster : public SerializationCluster {
|
||||
s->Push(code->ptr()->owner_);
|
||||
s->Push(code->ptr()->exception_handlers_);
|
||||
s->Push(code->ptr()->pc_descriptors_);
|
||||
#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
|
||||
s->Push(code->ptr()->catch_entry_.catch_entry_state_maps_);
|
||||
#else
|
||||
s->Push(code->ptr()->catch_entry_.variables_);
|
||||
#endif
|
||||
s->Push(code->ptr()->stackmaps_);
|
||||
s->Push(code->ptr()->inlined_id_to_function_);
|
||||
s->Push(code->ptr()->code_source_map_);
|
||||
@@ -1625,11 +1620,6 @@ class CodeSerializationCluster : public SerializationCluster {
|
||||
s->WriteRef(code->ptr()->owner_);
|
||||
s->WriteRef(code->ptr()->exception_handlers_);
|
||||
s->WriteRef(code->ptr()->pc_descriptors_);
|
||||
#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
|
||||
s->WriteRef(code->ptr()->catch_entry_.catch_entry_state_maps_);
|
||||
#else
|
||||
s->WriteRef(code->ptr()->catch_entry_.variables_);
|
||||
#endif
|
||||
s->WriteRef(code->ptr()->stackmaps_);
|
||||
s->WriteRef(code->ptr()->inlined_id_to_function_);
|
||||
s->WriteRef(code->ptr()->code_source_map_);
|
||||
@@ -1700,13 +1690,6 @@ class CodeDeserializationCluster : public DeserializationCluster {
|
||||
reinterpret_cast<RawExceptionHandlers*>(d->ReadRef());
|
||||
code->ptr()->pc_descriptors_ =
|
||||
reinterpret_cast<RawPcDescriptors*>(d->ReadRef());
|
||||
#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
|
||||
code->ptr()->catch_entry_.catch_entry_state_maps_ =
|
||||
reinterpret_cast<RawTypedData*>(d->ReadRef());
|
||||
#else
|
||||
code->ptr()->catch_entry_.variables_ =
|
||||
reinterpret_cast<RawSmi*>(d->ReadRef());
|
||||
#endif
|
||||
code->ptr()->stackmaps_ = reinterpret_cast<RawArray*>(d->ReadRef());
|
||||
code->ptr()->inlined_id_to_function_ =
|
||||
reinterpret_cast<RawArray*>(d->ReadRef());
|
||||
|
||||
@@ -125,103 +125,6 @@ static uint8_t* zone_allocator(uint8_t* ptr,
|
||||
}
|
||||
|
||||
|
||||
class CatchEntryStateMapBuilder::TrieNode : public ZoneAllocated {
|
||||
public:
|
||||
TrieNode() : pair_(), entry_state_offset_(-1) {}
|
||||
TrieNode(CatchEntryStatePair pair, intptr_t index)
|
||||
: pair_(pair), entry_state_offset_(index) {}
|
||||
|
||||
intptr_t Offset() { return entry_state_offset_; }
|
||||
|
||||
TrieNode* Insert(TrieNode* node) {
|
||||
children_.Add(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
TrieNode* Follow(CatchEntryStatePair next) {
|
||||
for (intptr_t i = 0; i < children_.length(); i++) {
|
||||
if (children_[i]->pair_ == next) return children_[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
CatchEntryStatePair pair_;
|
||||
const intptr_t entry_state_offset_;
|
||||
GrowableArray<TrieNode*> children_;
|
||||
};
|
||||
|
||||
CatchEntryStateMapBuilder::CatchEntryStateMapBuilder()
|
||||
: zone_(Thread::Current()->zone()),
|
||||
root_(new TrieNode()),
|
||||
current_pc_offset_(0),
|
||||
buffer_(NULL),
|
||||
stream_(&buffer_, zone_allocator, 64) {}
|
||||
|
||||
|
||||
void CatchEntryStateMapBuilder::AppendMove(intptr_t src_slot,
|
||||
intptr_t dest_slot) {
|
||||
moves_.Add(CatchEntryStatePair::FromMove(src_slot, dest_slot));
|
||||
}
|
||||
|
||||
|
||||
void CatchEntryStateMapBuilder::AppendConstant(intptr_t pool_id,
|
||||
intptr_t dest_slot) {
|
||||
moves_.Add(CatchEntryStatePair::FromConstant(pool_id, dest_slot));
|
||||
}
|
||||
|
||||
|
||||
void CatchEntryStateMapBuilder::NewMapping(intptr_t pc_offset) {
|
||||
moves_.Clear();
|
||||
current_pc_offset_ = pc_offset;
|
||||
}
|
||||
|
||||
|
||||
void CatchEntryStateMapBuilder::EndMapping() {
|
||||
intptr_t suffix_length = 0;
|
||||
TrieNode* suffix = root_;
|
||||
// Find the largest common suffix, get the last node of the path.
|
||||
for (intptr_t i = moves_.length() - 1; i >= 0; i--) {
|
||||
TrieNode* n = suffix->Follow(moves_[i]);
|
||||
if (n == NULL) break;
|
||||
suffix_length++;
|
||||
suffix = n;
|
||||
}
|
||||
intptr_t length = moves_.length() - suffix_length;
|
||||
intptr_t current_offset = stream_.bytes_written();
|
||||
|
||||
typedef WriteStream::Raw<sizeof(intptr_t), intptr_t> Writer;
|
||||
Writer::Write(&stream_, current_pc_offset_);
|
||||
Writer::Write(&stream_, length);
|
||||
Writer::Write(&stream_, suffix_length);
|
||||
Writer::Write(&stream_, suffix->Offset());
|
||||
|
||||
// Write the unshared part, adding it to the trie.
|
||||
TrieNode* node = suffix;
|
||||
for (intptr_t i = length - 1; i >= 0; i--) {
|
||||
Writer::Write(&stream_, moves_[i].src);
|
||||
Writer::Write(&stream_, moves_[i].dest);
|
||||
|
||||
TrieNode* child = new (zone_) TrieNode(moves_[i], current_offset);
|
||||
node->Insert(child);
|
||||
node = child;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RawTypedData* CatchEntryStateMapBuilder::FinalizeCatchEntryStateMap() {
|
||||
TypedData& td = TypedData::Handle(TypedData::New(
|
||||
kTypedDataInt8ArrayCid, stream_.bytes_written(), Heap::kOld));
|
||||
NoSafepointScope no_safepoint;
|
||||
uint8_t* dest = reinterpret_cast<uint8_t*>(td.DataAddr(0));
|
||||
uint8_t* src = stream_.buffer();
|
||||
for (intptr_t i = 0; i < stream_.bytes_written(); i++) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
return td.raw();
|
||||
}
|
||||
|
||||
|
||||
const TokenPosition CodeSourceMapBuilder::kInitialPosition =
|
||||
TokenPosition::kDartCodePrologue;
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "vm/ast.h"
|
||||
#include "vm/code_generator.h"
|
||||
#include "vm/datastream.h"
|
||||
#include "vm/globals.h"
|
||||
#include "vm/growable_array.h"
|
||||
#include "vm/object.h"
|
||||
@@ -149,59 +148,6 @@ class ExceptionHandlerList : public ZoneAllocated {
|
||||
};
|
||||
|
||||
|
||||
// An encoded move from stack/constant to stack performed
|
||||
struct CatchEntryStatePair {
|
||||
enum { kCatchEntryStateIsMove = 1, kCatchEntryStateDestShift = 1 };
|
||||
|
||||
intptr_t src, dest;
|
||||
|
||||
static CatchEntryStatePair FromConstant(intptr_t pool_id,
|
||||
intptr_t dest_slot) {
|
||||
CatchEntryStatePair pair;
|
||||
pair.src = pool_id;
|
||||
pair.dest = (dest_slot << kCatchEntryStateDestShift);
|
||||
return pair;
|
||||
}
|
||||
|
||||
static CatchEntryStatePair FromMove(intptr_t src_slot, intptr_t dest_slot) {
|
||||
CatchEntryStatePair pair;
|
||||
pair.src = src_slot;
|
||||
pair.dest =
|
||||
(dest_slot << kCatchEntryStateDestShift) | kCatchEntryStateIsMove;
|
||||
return pair;
|
||||
}
|
||||
|
||||
bool operator==(const CatchEntryStatePair& rhs) {
|
||||
return src == rhs.src && dest == rhs.dest;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Used to construct CatchEntryState metadata for AoT mode of compilation.
|
||||
class CatchEntryStateMapBuilder : public ZoneAllocated {
|
||||
public:
|
||||
CatchEntryStateMapBuilder();
|
||||
|
||||
void NewMapping(intptr_t pc_offset);
|
||||
void AppendMove(intptr_t src_slot, intptr_t dest_slot);
|
||||
void AppendConstant(intptr_t pool_id, intptr_t dest_slot);
|
||||
void EndMapping();
|
||||
RawTypedData* FinalizeCatchEntryStateMap();
|
||||
|
||||
private:
|
||||
class TrieNode;
|
||||
|
||||
Zone* zone_;
|
||||
TrieNode* root_;
|
||||
intptr_t current_pc_offset_;
|
||||
GrowableArray<CatchEntryStatePair> moves_;
|
||||
uint8_t* buffer_;
|
||||
WriteStream stream_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CatchEntryStateMapBuilder);
|
||||
};
|
||||
|
||||
|
||||
// A CodeSourceMap maps from pc offsets to a stack of inlined functions and
|
||||
// their positions. This is encoded as a little bytecode that pushes and pops
|
||||
// functions and changes the top function's position as the PC advances.
|
||||
|
||||
@@ -583,7 +583,6 @@ void CompileParsedFunctionHelper::FinalizeCompilation(
|
||||
graph_compiler->FinalizeStackMaps(code);
|
||||
graph_compiler->FinalizeVarDescriptors(code);
|
||||
graph_compiler->FinalizeExceptionHandlers(code);
|
||||
graph_compiler->FinalizeCatchEntryStateMap(code);
|
||||
graph_compiler->FinalizeStaticCallTargetsTable(code);
|
||||
graph_compiler->FinalizeCodeSourceMap(code);
|
||||
|
||||
|
||||
@@ -345,42 +345,6 @@ void DeoptContext::FillDestFrame() {
|
||||
}
|
||||
|
||||
|
||||
intptr_t* DeoptContext::CatchEntryState(intptr_t num_vars) {
|
||||
const Code& code = Code::Handle(code_);
|
||||
const TypedData& deopt_info = TypedData::Handle(deopt_info_);
|
||||
GrowableArray<DeoptInstr*> deopt_instructions;
|
||||
const Array& deopt_table = Array::Handle(code.deopt_info_array());
|
||||
ASSERT(!deopt_table.IsNull());
|
||||
DeoptInfo::Unpack(deopt_table, deopt_info, &deopt_instructions);
|
||||
|
||||
intptr_t* state = new intptr_t[2 * num_vars + 1];
|
||||
state[0] = num_vars;
|
||||
|
||||
Function& function = Function::Handle(zone(), code.function());
|
||||
intptr_t params =
|
||||
function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
|
||||
for (intptr_t i = 0; i < num_vars; i++) {
|
||||
#if defined(TARGET_ARCH_DBC)
|
||||
const intptr_t len = deopt_instructions.length();
|
||||
intptr_t slot = i < params ? i : i + kParamEndSlotFromFp;
|
||||
DeoptInstr* instr = deopt_instructions[len - 1 - slot];
|
||||
intptr_t dest_index = kNumberOfCpuRegisters - 1 - i;
|
||||
#else
|
||||
const intptr_t len = deopt_instructions.length();
|
||||
intptr_t slot =
|
||||
i < params ? i : i + kParamEndSlotFromFp - kFirstLocalSlotFromFp;
|
||||
DeoptInstr* instr = deopt_instructions[len - 1 - slot];
|
||||
intptr_t dest_index = i - params;
|
||||
#endif
|
||||
CatchEntryStatePair p = instr->ToCatchEntryStatePair(this, dest_index);
|
||||
state[1 + 2 * i] = p.src;
|
||||
state[2 + 2 * i] = p.dest;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
static void FillDeferredSlots(DeoptContext* deopt_context,
|
||||
DeferredSlot** slot_list) {
|
||||
DeferredSlot* slot = *slot_list;
|
||||
@@ -521,11 +485,6 @@ class DeoptConstantInstr : public DeoptInstr {
|
||||
*reinterpret_cast<RawObject**>(dest_addr) = obj.raw();
|
||||
}
|
||||
|
||||
CatchEntryStatePair ToCatchEntryStatePair(DeoptContext* deopt_context,
|
||||
intptr_t dest_slot) {
|
||||
return CatchEntryStatePair::FromConstant(object_table_index_, dest_slot);
|
||||
}
|
||||
|
||||
private:
|
||||
const intptr_t object_table_index_;
|
||||
|
||||
@@ -554,12 +513,6 @@ class DeoptWordInstr : public DeoptInstr {
|
||||
*dest_addr = source_.Value<intptr_t>(deopt_context);
|
||||
}
|
||||
|
||||
CatchEntryStatePair ToCatchEntryStatePair(DeoptContext* deopt_context,
|
||||
intptr_t dest_slot) {
|
||||
return CatchEntryStatePair::FromMove(source_.StackSlot(deopt_context),
|
||||
dest_slot);
|
||||
}
|
||||
|
||||
private:
|
||||
const CpuRegisterSource source_;
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "vm/allocation.h"
|
||||
#include "vm/assembler.h"
|
||||
#include "vm/code_descriptors.h"
|
||||
#include "vm/code_generator.h"
|
||||
#include "vm/deferred_objects.h"
|
||||
#include "vm/flow_graph_compiler.h"
|
||||
@@ -58,18 +57,6 @@ class DeoptContext {
|
||||
return &source_frame_[index];
|
||||
}
|
||||
|
||||
// Returns index in stack slot notation where -1 is the first argument
|
||||
// For DBC returns index directly relative to FP.
|
||||
intptr_t GetStackSlot(intptr_t index) const {
|
||||
ASSERT((0 <= index) && (index < source_frame_size_));
|
||||
index -= num_args_;
|
||||
#if defined(TARGET_ARCH_DBC)
|
||||
return index < 0 ? index - kDartFrameFixedSize : index;
|
||||
#else
|
||||
return index < 0 ? index : index - kDartFrameFixedSize;
|
||||
#endif // defined(TARGET_ARCH_DBC)
|
||||
}
|
||||
|
||||
intptr_t GetSourceFp() const;
|
||||
intptr_t GetSourcePp() const;
|
||||
intptr_t GetSourcePc() const;
|
||||
@@ -166,9 +153,6 @@ class DeoptContext {
|
||||
// objects.
|
||||
void FillDestFrame();
|
||||
|
||||
// Allocate and prepare exceptions metadata for TrySync
|
||||
intptr_t* CatchEntryState(intptr_t num_vars);
|
||||
|
||||
// Materializes all deferred objects. Returns the total number of
|
||||
// artificial arguments used during deoptimization.
|
||||
intptr_t MaterializeDeferredObjects();
|
||||
@@ -287,6 +271,7 @@ class DeoptContext {
|
||||
DISALLOW_COPY_AND_ASSIGN(DeoptContext);
|
||||
};
|
||||
|
||||
|
||||
// Represents one deopt instruction, e.g, setup return address, store object,
|
||||
// store register, etc. The target is defined by instruction's position in
|
||||
// the deopt-info array.
|
||||
@@ -334,13 +319,6 @@ class DeoptInstr : public ZoneAllocated {
|
||||
|
||||
virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0;
|
||||
|
||||
// Convert DeoptInstr to TrySync metadata entry.
|
||||
virtual CatchEntryStatePair ToCatchEntryStatePair(DeoptContext* deopt_context,
|
||||
intptr_t dest_slot) {
|
||||
UNREACHABLE();
|
||||
return CatchEntryStatePair();
|
||||
}
|
||||
|
||||
virtual DeoptInstr::Kind kind() const = 0;
|
||||
|
||||
bool Equals(const DeoptInstr& other) const {
|
||||
@@ -434,14 +412,6 @@ class RegisterSource {
|
||||
}
|
||||
}
|
||||
|
||||
intptr_t StackSlot(DeoptContext* context) const {
|
||||
if (is_register()) {
|
||||
return raw_index(); // in DBC stack slots are registers.
|
||||
} else {
|
||||
return context->GetStackSlot(raw_index());
|
||||
}
|
||||
}
|
||||
|
||||
intptr_t source_index() const { return source_index_; }
|
||||
|
||||
const char* ToCString() const {
|
||||
|
||||
+50
-203
@@ -10,9 +10,7 @@
|
||||
|
||||
#include "vm/dart_api_impl.h"
|
||||
#include "vm/dart_entry.h"
|
||||
#include "vm/datastream.h"
|
||||
#include "vm/debugger.h"
|
||||
#include "vm/deopt_instructions.h"
|
||||
#include "vm/flags.h"
|
||||
#include "vm/log.h"
|
||||
#include "vm/longjump.h"
|
||||
@@ -145,203 +143,52 @@ static void BuildStackTrace(StackTraceBuilder* builder) {
|
||||
}
|
||||
|
||||
|
||||
static RawObject** VariableAt(uword fp, int stack_slot) {
|
||||
#if defined(TARGET_ARCH_DBC)
|
||||
return reinterpret_cast<RawObject**>(fp + stack_slot * kWordSize);
|
||||
#else
|
||||
if (stack_slot < 0) {
|
||||
return reinterpret_cast<RawObject**>(ParamAddress(fp, -stack_slot));
|
||||
} else {
|
||||
return reinterpret_cast<RawObject**>(
|
||||
LocalVarAddress(fp, kFirstLocalSlotFromFp - stack_slot));
|
||||
// Iterate through the stack frames and try to find a frame with an
|
||||
// exception handler. Once found, set the pc, sp and fp so that execution
|
||||
// can continue in that frame. Sets 'needs_stacktrace' if there is no
|
||||
// cath-all handler or if a stack-trace is specified in the catch.
|
||||
static bool FindExceptionHandler(Thread* thread,
|
||||
uword* handler_pc,
|
||||
uword* handler_sp,
|
||||
uword* handler_fp,
|
||||
bool* needs_stacktrace) {
|
||||
StackFrameIterator frames(StackFrameIterator::kDontValidateFrames);
|
||||
StackFrame* frame = frames.NextFrame();
|
||||
if (frame == NULL) return false; // No Dart frame.
|
||||
bool handler_pc_set = false;
|
||||
*needs_stacktrace = false;
|
||||
bool is_catch_all = false;
|
||||
uword temp_handler_pc = kUwordMax;
|
||||
while (!frame->IsEntryFrame()) {
|
||||
if (frame->IsDartFrame()) {
|
||||
if (frame->FindExceptionHandler(thread, &temp_handler_pc,
|
||||
needs_stacktrace, &is_catch_all)) {
|
||||
if (!handler_pc_set) {
|
||||
handler_pc_set = true;
|
||||
*handler_pc = temp_handler_pc;
|
||||
*handler_sp = frame->sp();
|
||||
*handler_fp = frame->fp();
|
||||
}
|
||||
if (*needs_stacktrace || is_catch_all) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // if frame->IsDartFrame
|
||||
frame = frames.NextFrame();
|
||||
ASSERT(frame != NULL);
|
||||
} // while !frame->IsEntryFrame
|
||||
ASSERT(frame->IsEntryFrame());
|
||||
if (!handler_pc_set) {
|
||||
*handler_pc = frame->pc();
|
||||
*handler_sp = frame->sp();
|
||||
*handler_fp = frame->fp();
|
||||
}
|
||||
#endif
|
||||
// No catch-all encountered, needs stacktrace.
|
||||
*needs_stacktrace = true;
|
||||
return handler_pc_set;
|
||||
}
|
||||
|
||||
|
||||
class ExceptionHandlerFinder {
|
||||
public:
|
||||
explicit ExceptionHandlerFinder(Thread* thread)
|
||||
: thread_(thread), cache_(NULL), metadata_(NULL) {}
|
||||
|
||||
// Iterate through the stack frames and try to find a frame with an
|
||||
// exception handler. Once found, set the pc, sp and fp so that execution
|
||||
// can continue in that frame. Sets 'needs_stacktrace' if there is no
|
||||
// cath-all handler or if a stack-trace is specified in the catch.
|
||||
bool Find() {
|
||||
StackFrameIterator frames(StackFrameIterator::kDontValidateFrames);
|
||||
StackFrame* frame = frames.NextFrame();
|
||||
if (frame == NULL) return false; // No Dart frame.
|
||||
handler_pc_set_ = false;
|
||||
needs_stacktrace = false;
|
||||
bool is_catch_all = false;
|
||||
uword temp_handler_pc = kUwordMax;
|
||||
bool is_optimized = false;
|
||||
code_ = NULL;
|
||||
cache_ = thread_->isolate()->catch_entry_state_cache();
|
||||
|
||||
while (!frame->IsEntryFrame()) {
|
||||
if (frame->IsDartFrame()) {
|
||||
if (frame->FindExceptionHandler(thread_, &temp_handler_pc,
|
||||
&needs_stacktrace, &is_catch_all,
|
||||
&is_optimized)) {
|
||||
if (!handler_pc_set_) {
|
||||
handler_pc_set_ = true;
|
||||
handler_pc = temp_handler_pc;
|
||||
handler_sp = frame->sp();
|
||||
handler_fp = frame->fp();
|
||||
if (is_optimized) {
|
||||
pc_ = frame->pc();
|
||||
code_ = &Code::Handle(frame->LookupDartCode());
|
||||
cached_ = cache_->Lookup(pc_);
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER)
|
||||
intptr_t num_vars = Smi::Value(code_->variables());
|
||||
if (!cached_) GetMetaDataFromDeopt(num_vars, frame);
|
||||
#else
|
||||
if (!cached_) ReadCompressedMetaData();
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER)
|
||||
}
|
||||
}
|
||||
if (needs_stacktrace || is_catch_all) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // if frame->IsDartFrame
|
||||
frame = frames.NextFrame();
|
||||
ASSERT(frame != NULL);
|
||||
} // while !frame->IsEntryFrame
|
||||
ASSERT(frame->IsEntryFrame());
|
||||
if (!handler_pc_set_) {
|
||||
handler_pc = frame->pc();
|
||||
handler_sp = frame->sp();
|
||||
handler_fp = frame->fp();
|
||||
}
|
||||
// No catch-all encountered, needs stacktrace.
|
||||
needs_stacktrace = true;
|
||||
return handler_pc_set_;
|
||||
}
|
||||
|
||||
void TrySync() {
|
||||
if (code_ == NULL || !code_->is_optimized()) {
|
||||
return;
|
||||
}
|
||||
if (cached_) {
|
||||
// Cache hit.
|
||||
TrySyncCached(cached_);
|
||||
} else {
|
||||
// New cache entry.
|
||||
CatchEntryState m(metadata_);
|
||||
TrySyncCached(&m);
|
||||
}
|
||||
}
|
||||
|
||||
void TrySyncCached(CatchEntryState* md) {
|
||||
uword fp = handler_fp;
|
||||
ObjectPool* pool = NULL;
|
||||
intptr_t pairs = md->Pairs();
|
||||
for (int j = 0; j < pairs; j++) {
|
||||
intptr_t src = md->Src(j);
|
||||
intptr_t dest = md->Dest(j);
|
||||
if (md->isMove(j)) {
|
||||
*VariableAt(fp, dest) = *VariableAt(fp, src);
|
||||
} else {
|
||||
if (pool == NULL) {
|
||||
pool = &ObjectPool::Handle(code_->object_pool());
|
||||
}
|
||||
RawObject* obj = pool->ObjectAt(src);
|
||||
*VariableAt(fp, dest) = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
|
||||
void ReadCompressedMetaData() {
|
||||
intptr_t pc_offset = pc_ - code_->PayloadStart();
|
||||
const TypedData& td = TypedData::Handle(code_->catch_entry_state_maps());
|
||||
NoSafepointScope no_safepoint;
|
||||
ReadStream stream(static_cast<uint8_t*>(td.DataAddr(0)), td.Length());
|
||||
|
||||
bool found_metadata = false;
|
||||
while (stream.PendingBytes() > 0) {
|
||||
intptr_t target_pc_offset = Reader::Read(&stream);
|
||||
intptr_t variables = Reader::Read(&stream);
|
||||
intptr_t suffix_length = Reader::Read(&stream);
|
||||
intptr_t suffix_offset = Reader::Read(&stream);
|
||||
if (pc_offset == target_pc_offset) {
|
||||
metadata_ = new intptr_t[2 * (variables + suffix_length) + 1];
|
||||
metadata_[0] = variables + suffix_length;
|
||||
for (int j = 0; j < variables; j++) {
|
||||
intptr_t src = Reader::Read(&stream);
|
||||
intptr_t dest = Reader::Read(&stream);
|
||||
metadata_[1 + 2 * j] = src;
|
||||
metadata_[2 + 2 * j] = dest;
|
||||
}
|
||||
ReadCompressedSuffix(&stream, suffix_offset, suffix_length, metadata_,
|
||||
2 * variables + 1);
|
||||
found_metadata = true;
|
||||
break;
|
||||
} else {
|
||||
for (intptr_t j = 0; j < 2 * variables; j++) {
|
||||
Reader::Read(&stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
ASSERT(found_metadata);
|
||||
}
|
||||
|
||||
void ReadCompressedSuffix(ReadStream* stream,
|
||||
intptr_t offset,
|
||||
intptr_t length,
|
||||
intptr_t* target,
|
||||
intptr_t target_offset) {
|
||||
stream->SetPosition(offset);
|
||||
Reader::Read(stream); // skip pc_offset
|
||||
Reader::Read(stream); // skip variables
|
||||
intptr_t suffix_length = Reader::Read(stream);
|
||||
intptr_t suffix_offset = Reader::Read(stream);
|
||||
intptr_t to_read = length - suffix_length;
|
||||
for (int j = 0; j < to_read; j++) {
|
||||
target[target_offset + 2 * j] = Reader::Read(stream);
|
||||
target[target_offset + 2 * j + 1] = Reader::Read(stream);
|
||||
}
|
||||
if (suffix_length > 0) {
|
||||
ReadCompressedSuffix(stream, suffix_offset, suffix_length, target,
|
||||
target_offset + to_read * 2);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
void GetMetaDataFromDeopt(intptr_t num_vars, StackFrame* frame) {
|
||||
Isolate* isolate = thread_->isolate();
|
||||
DeoptContext* deopt_context =
|
||||
new DeoptContext(frame, *code_, DeoptContext::kDestIsAllocated, NULL,
|
||||
NULL, true, false /* deoptimizing_code */);
|
||||
isolate->set_deopt_context(deopt_context);
|
||||
|
||||
metadata_ = deopt_context->CatchEntryState(num_vars);
|
||||
|
||||
isolate->set_deopt_context(NULL);
|
||||
delete deopt_context;
|
||||
}
|
||||
#endif // defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
|
||||
|
||||
bool needs_stacktrace;
|
||||
uword handler_pc;
|
||||
uword handler_sp;
|
||||
uword handler_fp;
|
||||
|
||||
private:
|
||||
typedef ReadStream::Raw<sizeof(intptr_t), intptr_t> Reader;
|
||||
Thread* thread_;
|
||||
CatchEntryStateCache* cache_;
|
||||
Code* code_;
|
||||
bool handler_pc_set_;
|
||||
intptr_t* metadata_; // MetaData generated from deopt.
|
||||
CatchEntryState* cached_; // Value of per PC MetaData cache.
|
||||
intptr_t pc_; // Current pc in the handler frame.
|
||||
};
|
||||
|
||||
|
||||
static void FindErrorHandler(uword* handler_pc,
|
||||
uword* handler_sp,
|
||||
uword* handler_fp) {
|
||||
@@ -544,15 +391,16 @@ static void ThrowExceptionHelper(Thread* thread,
|
||||
exception.raw() == isolate->object_store()->stack_overflow()) {
|
||||
use_preallocated_stacktrace = true;
|
||||
}
|
||||
uword handler_pc = 0;
|
||||
uword handler_sp = 0;
|
||||
uword handler_fp = 0;
|
||||
Instance& stacktrace = Instance::Handle(zone);
|
||||
bool handler_exists = false;
|
||||
bool handler_needs_stacktrace = false;
|
||||
// Find the exception handler and determine if the handler needs a
|
||||
// stacktrace.
|
||||
ExceptionHandlerFinder finder(thread);
|
||||
bool handler_exists = finder.Find();
|
||||
uword handler_pc = finder.handler_pc;
|
||||
uword handler_sp = finder.handler_sp;
|
||||
uword handler_fp = finder.handler_fp;
|
||||
bool handler_needs_stacktrace = finder.needs_stacktrace;
|
||||
Instance& stacktrace = Instance::Handle(zone);
|
||||
handler_exists = FindExceptionHandler(thread, &handler_pc, &handler_sp,
|
||||
&handler_fp, &handler_needs_stacktrace);
|
||||
if (use_preallocated_stacktrace) {
|
||||
if (handler_pc == 0) {
|
||||
// No Dart frame.
|
||||
@@ -607,7 +455,6 @@ static void ThrowExceptionHelper(Thread* thread,
|
||||
THR_Print("%s\n", stacktrace.ToCString());
|
||||
}
|
||||
if (handler_exists) {
|
||||
finder.TrySync();
|
||||
// Found a dart handler for the exception, jump to it.
|
||||
JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp,
|
||||
exception, stacktrace);
|
||||
|
||||
@@ -102,31 +102,6 @@ struct ExceptionHandlerInfo {
|
||||
int8_t is_generated; // True if this is a generated handler.
|
||||
};
|
||||
|
||||
|
||||
class CatchEntryState {
|
||||
public:
|
||||
enum { kCatchEntryStateIsMove = 1, kCatchEntryStateDestShift = 1 };
|
||||
|
||||
CatchEntryState() : data(NULL) {}
|
||||
explicit CatchEntryState(intptr_t* data_) : data(data_) {}
|
||||
// Data has the following format:
|
||||
// 0 - number of pairs in this state
|
||||
// 1-2 - 1st encoded src,dest pair
|
||||
// 3-4 - 2nd pair
|
||||
// ....
|
||||
intptr_t* data;
|
||||
|
||||
intptr_t Pairs() { return data[0]; }
|
||||
|
||||
intptr_t Src(intptr_t i) { return data[1 + 2 * i]; }
|
||||
|
||||
intptr_t Dest(intptr_t i) {
|
||||
return data[2 + 2 * i] >> kCatchEntryStateDestShift;
|
||||
}
|
||||
|
||||
bool isMove(intptr_t i) { return data[2 + 2 * i] & kCatchEntryStateIsMove; }
|
||||
};
|
||||
|
||||
} // namespace dart
|
||||
|
||||
#endif // RUNTIME_VM_EXCEPTIONS_H_
|
||||
|
||||
@@ -196,7 +196,6 @@ FlowGraphCompiler::FlowGraphCompiler(
|
||||
pc_descriptors_list_(NULL),
|
||||
stackmap_table_builder_(NULL),
|
||||
code_source_map_builder_(NULL),
|
||||
catch_entry_state_maps_builder_(NULL),
|
||||
block_info_(block_order_.length()),
|
||||
deopt_infos_(),
|
||||
static_calls_target_table_(),
|
||||
@@ -268,7 +267,6 @@ bool FlowGraphCompiler::IsPotentialUnboxedField(const Field& field) {
|
||||
void FlowGraphCompiler::InitCompiler() {
|
||||
pc_descriptors_list_ = new (zone()) DescriptorList(64);
|
||||
exception_handlers_list_ = new (zone()) ExceptionHandlerList();
|
||||
catch_entry_state_maps_builder_ = new (zone()) CatchEntryStateMapBuilder();
|
||||
block_info_.Clear();
|
||||
// Conservative detection of leaf routines used to remove the stack check
|
||||
// on function entry.
|
||||
@@ -414,91 +412,6 @@ void FlowGraphCompiler::CompactBlocks() {
|
||||
}
|
||||
|
||||
|
||||
void FlowGraphCompiler::EmitCatchEntryState(Environment* env,
|
||||
intptr_t try_index) {
|
||||
#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
|
||||
env = env ? env : pending_deoptimization_env_;
|
||||
try_index = try_index != CatchClauseNode::kInvalidTryIndex
|
||||
? try_index
|
||||
: CurrentTryIndex();
|
||||
if (is_optimizing() && env != NULL &&
|
||||
(try_index != CatchClauseNode::kInvalidTryIndex)) {
|
||||
env = env->Outermost();
|
||||
CatchBlockEntryInstr* catch_block =
|
||||
flow_graph().graph_entry()->GetCatchEntry(try_index);
|
||||
const GrowableArray<Definition*>* idefs =
|
||||
catch_block->initial_definitions();
|
||||
catch_entry_state_maps_builder_->NewMapping(assembler()->CodeSize());
|
||||
// Parameters first.
|
||||
intptr_t i = 0;
|
||||
const intptr_t num_non_copied_params = flow_graph().num_non_copied_params();
|
||||
for (; i < num_non_copied_params; ++i) {
|
||||
// Don't sync captured parameters. They are not in the environment.
|
||||
if (flow_graph().captured_parameters()->Contains(i)) continue;
|
||||
if ((*idefs)[i]->IsConstant()) continue; // Common constants.
|
||||
Location src = env->LocationAt(i);
|
||||
intptr_t dest_index = i - num_non_copied_params;
|
||||
if (!src.IsStackSlot()) {
|
||||
ASSERT(src.IsConstant());
|
||||
// Skip dead locations.
|
||||
if (src.constant().raw() == Symbols::OptimizedOut().raw()) {
|
||||
continue;
|
||||
}
|
||||
intptr_t id =
|
||||
assembler()->object_pool_wrapper().FindObject(src.constant());
|
||||
catch_entry_state_maps_builder_->AppendConstant(id, dest_index);
|
||||
continue;
|
||||
}
|
||||
if (src.stack_index() != dest_index) {
|
||||
catch_entry_state_maps_builder_->AppendMove(src.stack_index(),
|
||||
dest_index);
|
||||
}
|
||||
}
|
||||
|
||||
// Process locals. Skip exception_var and stacktrace_var.
|
||||
intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params;
|
||||
intptr_t ex_idx = local_base - catch_block->exception_var().index();
|
||||
intptr_t st_idx = local_base - catch_block->stacktrace_var().index();
|
||||
for (; i < flow_graph().variable_count(); ++i) {
|
||||
// Don't sync captured parameters. They are not in the environment.
|
||||
if (flow_graph().captured_parameters()->Contains(i)) continue;
|
||||
if (i == ex_idx || i == st_idx) continue;
|
||||
if ((*idefs)[i]->IsConstant()) continue; // Common constants.
|
||||
Location src = env->LocationAt(i);
|
||||
if (src.IsInvalid()) continue;
|
||||
intptr_t dest_index = i - num_non_copied_params;
|
||||
if (!src.IsStackSlot()) {
|
||||
ASSERT(src.IsConstant());
|
||||
// Skip dead locations.
|
||||
if (src.constant().raw() == Symbols::OptimizedOut().raw()) {
|
||||
continue;
|
||||
}
|
||||
intptr_t id =
|
||||
assembler()->object_pool_wrapper().FindObject(src.constant());
|
||||
catch_entry_state_maps_builder_->AppendConstant(id, dest_index);
|
||||
continue;
|
||||
}
|
||||
if (src.stack_index() != dest_index) {
|
||||
catch_entry_state_maps_builder_->AppendMove(src.stack_index(),
|
||||
dest_index);
|
||||
}
|
||||
}
|
||||
catch_entry_state_maps_builder_->EndMapping();
|
||||
}
|
||||
#endif // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
|
||||
}
|
||||
|
||||
|
||||
void FlowGraphCompiler::EmitCallsiteMetaData(TokenPosition token_pos,
|
||||
intptr_t deopt_id,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
AddCurrentDescriptor(kind, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
EmitCatchEntryState();
|
||||
}
|
||||
|
||||
|
||||
void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
|
||||
if (!is_optimizing()) {
|
||||
if (instr->CanBecomeDeoptimizationTarget() && !instr->IsGoto()) {
|
||||
@@ -509,6 +422,10 @@ void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
|
||||
instr->token_pos());
|
||||
}
|
||||
AllocateRegistersLocally(instr);
|
||||
} else if (instr->MayThrow() &&
|
||||
(CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
|
||||
// Optimized try-block: Sync locals to fixed stack locations.
|
||||
EmitTrySync(instr, CurrentTryIndex());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,6 +544,69 @@ void FlowGraphCompiler::Bailout(const char* reason) {
|
||||
}
|
||||
|
||||
|
||||
void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) {
|
||||
ASSERT(is_optimizing());
|
||||
Environment* env = instr->env()->Outermost();
|
||||
CatchBlockEntryInstr* catch_block =
|
||||
flow_graph().graph_entry()->GetCatchEntry(try_index);
|
||||
const GrowableArray<Definition*>* idefs = catch_block->initial_definitions();
|
||||
|
||||
// Construct a ParallelMove instruction for parameters and locals. Skip the
|
||||
// special locals exception_var and stacktrace_var since they will be filled
|
||||
// when an exception is thrown. Constant locations are known to be the same
|
||||
// at all instructions that may throw, and do not need to be materialized.
|
||||
|
||||
// Parameters first.
|
||||
intptr_t i = 0;
|
||||
const intptr_t num_non_copied_params = flow_graph().num_non_copied_params();
|
||||
ParallelMoveInstr* move_instr = new (zone()) ParallelMoveInstr();
|
||||
for (; i < num_non_copied_params; ++i) {
|
||||
// Don't sync captured parameters. They are not in the environment.
|
||||
if (flow_graph().captured_parameters()->Contains(i)) continue;
|
||||
if ((*idefs)[i]->IsConstant()) continue; // Common constants
|
||||
Location src = env->LocationAt(i);
|
||||
#if defined(TARGET_ARCH_DBC)
|
||||
intptr_t dest_index = kNumberOfCpuRegisters - 1 - i;
|
||||
Location dest = Location::RegisterLocation(dest_index);
|
||||
// Update safepoint bitmap to indicate that the target location
|
||||
// now contains a pointer. With DBC parameters are copied into
|
||||
// the locals area.
|
||||
instr->locs()->SetStackBit(dest_index);
|
||||
#else
|
||||
intptr_t dest_index = i - num_non_copied_params;
|
||||
Location dest = Location::StackSlot(dest_index);
|
||||
#endif
|
||||
move_instr->AddMove(dest, src);
|
||||
}
|
||||
|
||||
// Process locals. Skip exception_var and stacktrace_var.
|
||||
intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params;
|
||||
intptr_t ex_idx = local_base - catch_block->exception_var().index();
|
||||
intptr_t st_idx = local_base - catch_block->stacktrace_var().index();
|
||||
for (; i < flow_graph().variable_count(); ++i) {
|
||||
// Don't sync captured parameters. They are not in the environment.
|
||||
if (flow_graph().captured_parameters()->Contains(i)) continue;
|
||||
if (i == ex_idx || i == st_idx) continue;
|
||||
if ((*idefs)[i]->IsConstant()) continue;
|
||||
Location src = env->LocationAt(i);
|
||||
ASSERT(!src.IsFpuRegister());
|
||||
ASSERT(!src.IsDoubleStackSlot());
|
||||
#if defined(TARGET_ARCH_DBC)
|
||||
intptr_t dest_index = kNumberOfCpuRegisters - 1 - i;
|
||||
Location dest = Location::RegisterLocation(dest_index);
|
||||
#else
|
||||
intptr_t dest_index = i - num_non_copied_params;
|
||||
Location dest = Location::StackSlot(dest_index);
|
||||
#endif
|
||||
move_instr->AddMove(dest, src);
|
||||
// Update safepoint bitmap to indicate that the target location
|
||||
// now contains a pointer.
|
||||
instr->locs()->SetStackBit(dest_index);
|
||||
}
|
||||
parallel_move_resolver()->EmitNativeCode(move_instr);
|
||||
}
|
||||
|
||||
|
||||
intptr_t FlowGraphCompiler::StackSize() const {
|
||||
if (is_optimizing_) {
|
||||
return flow_graph_.graph_entry()->spill_slot_count();
|
||||
@@ -1035,15 +1015,6 @@ void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
|
||||
code.set_var_descriptors(var_descs);
|
||||
}
|
||||
|
||||
void FlowGraphCompiler::FinalizeCatchEntryStateMap(const Code& code) {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
|
||||
TypedData& maps = TypedData::Handle(
|
||||
catch_entry_state_maps_builder_->FinalizeCatchEntryStateMap());
|
||||
code.set_catch_entry_state_maps(maps);
|
||||
#else
|
||||
code.set_variables(Smi::Handle(Smi::New(flow_graph().variable_count())));
|
||||
#endif
|
||||
}
|
||||
|
||||
void FlowGraphCompiler::FinalizeStaticCallTargetsTable(const Code& code) {
|
||||
ASSERT(code.static_calls_target_table() == Array::null());
|
||||
@@ -1071,7 +1042,6 @@ void FlowGraphCompiler::FinalizeStaticCallTargetsTable(const Code& code) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FlowGraphCompiler::FinalizeCodeSourceMap(const Code& code) {
|
||||
const Array& inlined_id_array =
|
||||
Array::Handle(zone(), code_source_map_builder_->InliningIdToFunction());
|
||||
@@ -1153,23 +1123,6 @@ bool FlowGraphCompiler::TryIntrinsify() {
|
||||
// DBC is very different from other architectures in how it performs instance
|
||||
// and static calls because it does not use stubs.
|
||||
#if !defined(TARGET_ARCH_DBC)
|
||||
void FlowGraphCompiler::GenerateCallWithDeopt(TokenPosition token_pos,
|
||||
intptr_t deopt_id,
|
||||
const StubEntry& stub_entry,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
GenerateCall(token_pos, stub_entry, kind, locs);
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
if (is_optimizing()) {
|
||||
AddDeoptIndexAtCall(deopt_id_after);
|
||||
} else {
|
||||
// Add deoptimization continuation point after the call and before the
|
||||
// arguments are removed.
|
||||
AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FlowGraphCompiler::GenerateInstanceCall(intptr_t deopt_id,
|
||||
TokenPosition token_pos,
|
||||
intptr_t argument_count,
|
||||
|
||||
@@ -23,7 +23,6 @@ template <typename T>
|
||||
class GrowableArray;
|
||||
class ParsedFunction;
|
||||
|
||||
|
||||
class ParallelMoveResolver : public ValueObject {
|
||||
public:
|
||||
explicit ParallelMoveResolver(FlowGraphCompiler* compiler);
|
||||
@@ -362,12 +361,6 @@ class FlowGraphCompiler : public ValueObject {
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs);
|
||||
|
||||
void GenerateCallWithDeopt(TokenPosition token_pos,
|
||||
intptr_t deopt_id,
|
||||
const StubEntry& stub_entry,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs);
|
||||
|
||||
void GeneratePatchableCall(TokenPosition token_pos,
|
||||
const StubEntry& stub_entry,
|
||||
RawPcDescriptors::Kind kind,
|
||||
@@ -474,14 +467,8 @@ class FlowGraphCompiler : public ValueObject {
|
||||
|
||||
void EmitEdgeCounter(intptr_t edge_id);
|
||||
#endif // !defined(TARGET_ARCH_DBC)
|
||||
void EmitCatchEntryState(
|
||||
Environment* env = NULL,
|
||||
intptr_t try_index = CatchClauseNode::kInvalidTryIndex);
|
||||
|
||||
void EmitCallsiteMetaData(TokenPosition token_pos,
|
||||
intptr_t deopt_id,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs);
|
||||
void EmitTrySync(Instruction* instr, intptr_t try_index);
|
||||
|
||||
void EmitComment(Instruction* instr);
|
||||
|
||||
@@ -543,7 +530,6 @@ class FlowGraphCompiler : public ValueObject {
|
||||
RawArray* CreateDeoptInfo(Assembler* assembler);
|
||||
void FinalizeStackMaps(const Code& code);
|
||||
void FinalizeVarDescriptors(const Code& code);
|
||||
void FinalizeCatchEntryStateMap(const Code& code);
|
||||
void FinalizeStaticCallTargetsTable(const Code& code);
|
||||
void FinalizeCodeSourceMap(const Code& code);
|
||||
|
||||
@@ -623,8 +609,6 @@ class FlowGraphCompiler : public ValueObject {
|
||||
|
||||
private:
|
||||
friend class CheckStackOverflowSlowPath; // For pending_deoptimization_env_.
|
||||
friend class CheckedSmiSlowPath; // Same.
|
||||
friend class CheckedSmiComparisonSlowPath; // Same.
|
||||
|
||||
static bool ShouldInlineSmiStringHashCode(const ICData& ic_data);
|
||||
|
||||
@@ -787,7 +771,6 @@ class FlowGraphCompiler : public ValueObject {
|
||||
DescriptorList* pc_descriptors_list_;
|
||||
StackMapTableBuilder* stackmap_table_builder_;
|
||||
CodeSourceMapBuilder* code_source_map_builder_;
|
||||
CatchEntryStateMapBuilder* catch_entry_state_maps_builder_;
|
||||
GrowableArray<BlockInfo*> block_info_;
|
||||
GrowableArray<CompilerDeoptInfo*> deopt_infos_;
|
||||
GrowableArray<SlowPathCode*> slow_path_code_;
|
||||
|
||||
@@ -1082,7 +1082,8 @@ void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ BranchLink(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs);
|
||||
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
}
|
||||
|
||||
|
||||
@@ -1091,7 +1092,8 @@ void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ BranchLinkPatchable(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs);
|
||||
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
}
|
||||
|
||||
|
||||
@@ -1101,7 +1103,8 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ BranchLinkPatchable(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, kind, locs);
|
||||
AddCurrentDescriptor(kind, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
@@ -1127,7 +1130,8 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
|
||||
ASSERT(is_optimizing());
|
||||
__ BranchLinkWithEquivalence(stub_entry, target);
|
||||
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, kind, locs);
|
||||
AddCurrentDescriptor(kind, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
@@ -1148,7 +1152,8 @@ void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
|
||||
intptr_t argument_count,
|
||||
LocationSummary* locs) {
|
||||
__ CallRuntime(entry, argument_count);
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
|
||||
AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
if (deopt_id != Thread::kNoDeoptId) {
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
@@ -1290,7 +1295,6 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
||||
// arguments are removed.
|
||||
AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
|
||||
}
|
||||
EmitCatchEntryState(pending_deoptimization_env_, try_index);
|
||||
__ Drop(argument_count);
|
||||
}
|
||||
|
||||
@@ -1312,8 +1316,8 @@ void FlowGraphCompiler::EmitSwitchableInstanceCall(const ICData& ic_data,
|
||||
__ LoadUniqueObject(R9, ic_data);
|
||||
__ blx(LR);
|
||||
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, RawPcDescriptors::kOther,
|
||||
locs);
|
||||
AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
if (is_optimizing()) {
|
||||
AddDeoptIndexAtCall(deopt_id_after);
|
||||
|
||||
@@ -1078,7 +1078,8 @@ void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ BranchLink(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs);
|
||||
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
}
|
||||
|
||||
|
||||
@@ -1087,7 +1088,8 @@ void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ BranchLinkPatchable(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs);
|
||||
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
}
|
||||
|
||||
|
||||
@@ -1097,7 +1099,8 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ BranchLinkPatchable(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, kind, locs);
|
||||
AddCurrentDescriptor(kind, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
@@ -1123,7 +1126,8 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
|
||||
ASSERT(is_optimizing());
|
||||
__ BranchLinkWithEquivalence(stub_entry, target);
|
||||
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, kind, locs);
|
||||
AddCurrentDescriptor(kind, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
@@ -1144,7 +1148,8 @@ void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
|
||||
intptr_t argument_count,
|
||||
LocationSummary* locs) {
|
||||
__ CallRuntime(entry, argument_count);
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
|
||||
AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
if (deopt_id != Thread::kNoDeoptId) {
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
@@ -1278,7 +1283,6 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
||||
// arguments are removed.
|
||||
AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
|
||||
}
|
||||
EmitCatchEntryState(pending_deoptimization_env_, try_index);
|
||||
__ Drop(argument_count);
|
||||
}
|
||||
|
||||
@@ -1299,8 +1303,8 @@ void FlowGraphCompiler::EmitSwitchableInstanceCall(const ICData& ic_data,
|
||||
__ LoadUniqueObject(R5, ic_data);
|
||||
__ blr(TMP);
|
||||
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, RawPcDescriptors::kOther,
|
||||
locs);
|
||||
AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
if (is_optimizing()) {
|
||||
AddDeoptIndexAtCall(deopt_id_after);
|
||||
|
||||
@@ -1084,7 +1084,8 @@ void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ Call(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs);
|
||||
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
}
|
||||
|
||||
|
||||
@@ -1094,7 +1095,8 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ Call(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, kind, locs);
|
||||
AddCurrentDescriptor(kind, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
@@ -1114,7 +1116,8 @@ void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
|
||||
intptr_t argument_count,
|
||||
LocationSummary* locs) {
|
||||
__ CallRuntime(entry, argument_count);
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
|
||||
AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
if (deopt_id != Thread::kNoDeoptId) {
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
@@ -1245,7 +1248,6 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
||||
// arguments are removed.
|
||||
AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
|
||||
}
|
||||
EmitCatchEntryState(pending_deoptimization_env_, try_index);
|
||||
__ Drop(argument_count);
|
||||
}
|
||||
|
||||
|
||||
@@ -1098,7 +1098,8 @@ void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ BranchLink(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs);
|
||||
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
}
|
||||
|
||||
|
||||
@@ -1107,7 +1108,8 @@ void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ BranchLinkPatchable(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs);
|
||||
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
}
|
||||
|
||||
|
||||
@@ -1117,7 +1119,8 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ BranchLinkPatchable(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, kind, locs);
|
||||
AddCurrentDescriptor(kind, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
@@ -1143,7 +1146,8 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
|
||||
ASSERT(is_optimizing());
|
||||
__ BranchLinkWithEquivalence(stub_entry, target);
|
||||
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, kind, locs);
|
||||
AddCurrentDescriptor(kind, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
@@ -1164,7 +1168,8 @@ void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
|
||||
intptr_t argument_count,
|
||||
LocationSummary* locs) {
|
||||
__ CallRuntime(entry, argument_count);
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
|
||||
AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
if (deopt_id != Thread::kNoDeoptId) {
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
@@ -1295,7 +1300,6 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
||||
// arguments are removed.
|
||||
AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
|
||||
}
|
||||
EmitCatchEntryState(pending_deoptimization_env_, try_index);
|
||||
__ Drop(argument_count);
|
||||
}
|
||||
|
||||
@@ -1316,8 +1320,8 @@ void FlowGraphCompiler::EmitSwitchableInstanceCall(const ICData& ic_data,
|
||||
__ LoadUniqueObject(S5, ic_data);
|
||||
__ jalr(T9);
|
||||
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, RawPcDescriptors::kOther,
|
||||
locs);
|
||||
AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
if (is_optimizing()) {
|
||||
AddDeoptIndexAtCall(deopt_id_after);
|
||||
|
||||
@@ -1082,7 +1082,8 @@ void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ Call(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs);
|
||||
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
}
|
||||
|
||||
|
||||
@@ -1091,7 +1092,8 @@ void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ CallPatchable(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs);
|
||||
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
}
|
||||
|
||||
|
||||
@@ -1101,7 +1103,8 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
|
||||
RawPcDescriptors::Kind kind,
|
||||
LocationSummary* locs) {
|
||||
__ CallPatchable(stub_entry);
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, kind, locs);
|
||||
AddCurrentDescriptor(kind, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
@@ -1127,7 +1130,8 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id,
|
||||
ASSERT(is_optimizing());
|
||||
__ CallWithEquivalence(stub_entry, target);
|
||||
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, kind, locs);
|
||||
AddCurrentDescriptor(kind, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
@@ -1148,7 +1152,8 @@ void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
|
||||
intptr_t argument_count,
|
||||
LocationSummary* locs) {
|
||||
__ CallRuntime(entry, argument_count);
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
|
||||
AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
if (deopt_id != Thread::kNoDeoptId) {
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
@@ -1287,7 +1292,6 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
|
||||
// arguments are removed.
|
||||
AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
|
||||
}
|
||||
EmitCatchEntryState(pending_deoptimization_env_, try_index);
|
||||
__ Drop(argument_count, RCX);
|
||||
}
|
||||
|
||||
@@ -1308,8 +1312,8 @@ void FlowGraphCompiler::EmitSwitchableInstanceCall(const ICData& ic_data,
|
||||
__ LoadUniqueObject(RBX, ic_data);
|
||||
__ call(RCX);
|
||||
|
||||
|
||||
EmitCallsiteMetaData(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
|
||||
AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos);
|
||||
RecordSafepoint(locs);
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
|
||||
if (is_optimizing()) {
|
||||
AddDeoptIndexAtCall(deopt_id_after);
|
||||
|
||||
@@ -405,7 +405,6 @@ void Heap::CollectOldSpaceGarbage(Thread* thread,
|
||||
NOT_IN_PRODUCT(PrintStatsToTimeline(&tds));
|
||||
// Some Code objects may have been collected so invalidate handler cache.
|
||||
thread->isolate()->handler_info_cache()->Clear();
|
||||
thread->isolate()->catch_entry_state_cache()->Clear();
|
||||
EndOldSpaceGC();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +241,6 @@ void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
__ LoadImmediate(R9, 0);
|
||||
__ blx(R2);
|
||||
compiler->RecordSafepoint(locs());
|
||||
compiler->EmitCatchEntryState();
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
|
||||
@@ -2477,9 +2476,8 @@ void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
const Code& stub = Code::ZoneHandle(compiler->zone(),
|
||||
StubCode::AllocateArray_entry()->code());
|
||||
compiler->AddStubCallTarget(stub);
|
||||
compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
|
||||
*StubCode::AllocateArray_entry(),
|
||||
RawPcDescriptors::kOther, locs());
|
||||
compiler->GenerateCall(token_pos(), *StubCode::AllocateArray_entry(),
|
||||
RawPcDescriptors::kOther, locs());
|
||||
ASSERT(locs()->out(0).reg() == kResultReg);
|
||||
}
|
||||
|
||||
@@ -3129,10 +3127,6 @@ class CheckedSmiSlowPath : public SlowPathCode {
|
||||
locs->live_registers()->Remove(Location::RegisterLocation(result));
|
||||
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
if (instruction_->env() != NULL) {
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->pending_deoptimization_env_ = env;
|
||||
}
|
||||
__ Push(locs->in(0).reg());
|
||||
__ Push(locs->in(1).reg());
|
||||
compiler->EmitMegamorphicInstanceCall(
|
||||
@@ -3143,7 +3137,6 @@ class CheckedSmiSlowPath : public SlowPathCode {
|
||||
__ mov(result, Operand(R0));
|
||||
compiler->RestoreLiveRegisters(locs);
|
||||
__ b(exit_label());
|
||||
compiler->pending_deoptimization_env_ = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -3268,10 +3261,6 @@ class CheckedSmiComparisonSlowPath : public SlowPathCode {
|
||||
locs->live_registers()->Remove(Location::RegisterLocation(result));
|
||||
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
if (instruction_->env() != NULL) {
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->pending_deoptimization_env_ = env;
|
||||
}
|
||||
__ Push(locs->in(0).reg());
|
||||
__ Push(locs->in(1).reg());
|
||||
compiler->EmitMegamorphicInstanceCall(
|
||||
@@ -3281,7 +3270,6 @@ class CheckedSmiComparisonSlowPath : public SlowPathCode {
|
||||
/* slow_path_argument_count = */ 2);
|
||||
__ mov(result, Operand(R0));
|
||||
compiler->RestoreLiveRegisters(locs);
|
||||
compiler->pending_deoptimization_env_ = NULL;
|
||||
if (merged_) {
|
||||
__ CompareObject(result, Bool::True());
|
||||
__ b(
|
||||
@@ -6411,7 +6399,6 @@ class RangeErrorSlowPath : public SlowPathCode {
|
||||
}
|
||||
__ Bind(entry_label());
|
||||
LocationSummary* locs = instruction_->locs();
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
__ Push(locs->in(0).reg());
|
||||
__ Push(locs->in(1).reg());
|
||||
__ CallRuntime(kRangeErrorRuntimeEntry, 2);
|
||||
@@ -6419,8 +6406,6 @@ class RangeErrorSlowPath : public SlowPathCode {
|
||||
RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
|
||||
instruction_->deopt_id(), instruction_->token_pos(), try_index_);
|
||||
compiler->RecordSafepoint(locs, 2);
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->EmitCatchEntryState(env, try_index_);
|
||||
__ bkpt(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -237,7 +237,6 @@ void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
//??
|
||||
__ blr(R2);
|
||||
compiler->RecordSafepoint(locs());
|
||||
compiler->EmitCatchEntryState();
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
|
||||
@@ -2207,9 +2206,8 @@ void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
const Code& stub = Code::ZoneHandle(compiler->zone(),
|
||||
StubCode::AllocateArray_entry()->code());
|
||||
compiler->AddStubCallTarget(stub);
|
||||
compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
|
||||
*StubCode::AllocateArray_entry(),
|
||||
RawPcDescriptors::kOther, locs());
|
||||
compiler->GenerateCall(token_pos(), *StubCode::AllocateArray_entry(),
|
||||
RawPcDescriptors::kOther, locs());
|
||||
ASSERT(locs()->out(0).reg() == kResultReg);
|
||||
}
|
||||
|
||||
@@ -2829,10 +2827,6 @@ class CheckedSmiSlowPath : public SlowPathCode {
|
||||
locs->live_registers()->Remove(Location::RegisterLocation(result));
|
||||
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
if (instruction_->env() != NULL) {
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->pending_deoptimization_env_ = env;
|
||||
}
|
||||
__ Push(locs->in(0).reg());
|
||||
__ Push(locs->in(1).reg());
|
||||
compiler->EmitMegamorphicInstanceCall(
|
||||
@@ -2843,7 +2837,6 @@ class CheckedSmiSlowPath : public SlowPathCode {
|
||||
__ mov(result, R0);
|
||||
compiler->RestoreLiveRegisters(locs);
|
||||
__ b(exit_label());
|
||||
compiler->pending_deoptimization_env_ = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -2971,10 +2964,6 @@ class CheckedSmiComparisonSlowPath : public SlowPathCode {
|
||||
locs->live_registers()->Remove(Location::RegisterLocation(result));
|
||||
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
if (instruction_->env() != NULL) {
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->pending_deoptimization_env_ = env;
|
||||
}
|
||||
__ Push(locs->in(0).reg());
|
||||
__ Push(locs->in(1).reg());
|
||||
compiler->EmitMegamorphicInstanceCall(
|
||||
@@ -2984,7 +2973,6 @@ class CheckedSmiComparisonSlowPath : public SlowPathCode {
|
||||
/* slow_path_argument_count = */ 2);
|
||||
__ mov(result, R0);
|
||||
compiler->RestoreLiveRegisters(locs);
|
||||
compiler->pending_deoptimization_env_ = NULL;
|
||||
if (merged_) {
|
||||
__ CompareObject(result, Bool::True());
|
||||
__ b(
|
||||
@@ -5558,7 +5546,6 @@ class RangeErrorSlowPath : public SlowPathCode {
|
||||
}
|
||||
__ Bind(entry_label());
|
||||
LocationSummary* locs = instruction_->locs();
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
__ Push(locs->in(0).reg());
|
||||
__ Push(locs->in(1).reg());
|
||||
__ CallRuntime(kRangeErrorRuntimeEntry, 2);
|
||||
@@ -5566,8 +5553,6 @@ class RangeErrorSlowPath : public SlowPathCode {
|
||||
RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
|
||||
instruction_->deopt_id(), instruction_->token_pos(), try_index_);
|
||||
compiler->RecordSafepoint(locs, 2);
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->EmitCatchEntryState(env, try_index_);
|
||||
__ brk(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2117,9 +2117,8 @@ void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
const Code& stub = Code::ZoneHandle(compiler->zone(),
|
||||
StubCode::AllocateArray_entry()->code());
|
||||
compiler->AddStubCallTarget(stub);
|
||||
compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
|
||||
*StubCode::AllocateArray_entry(),
|
||||
RawPcDescriptors::kOther, locs());
|
||||
compiler->GenerateCall(token_pos(), *StubCode::AllocateArray_entry(),
|
||||
RawPcDescriptors::kOther, locs());
|
||||
__ Bind(&done);
|
||||
ASSERT(locs()->out(0).reg() == kResultReg);
|
||||
}
|
||||
|
||||
@@ -300,7 +300,6 @@ void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
__ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
|
||||
__ jalr(T2);
|
||||
compiler->RecordSafepoint(locs());
|
||||
compiler->EmitCatchEntryState();
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
|
||||
@@ -2351,9 +2350,8 @@ void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
const Code& stub = Code::ZoneHandle(compiler->zone(),
|
||||
StubCode::AllocateArray_entry()->code());
|
||||
compiler->AddStubCallTarget(stub);
|
||||
compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
|
||||
*StubCode::AllocateArray_entry(),
|
||||
RawPcDescriptors::kOther, locs());
|
||||
compiler->GenerateCall(token_pos(), *StubCode::AllocateArray_entry(),
|
||||
RawPcDescriptors::kOther, locs());
|
||||
__ Bind(&done);
|
||||
ASSERT(locs()->out(0).reg() == kResultReg);
|
||||
}
|
||||
@@ -2965,10 +2963,6 @@ class CheckedSmiSlowPath : public SlowPathCode {
|
||||
locs->live_registers()->Remove(Location::RegisterLocation(result));
|
||||
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
if (instruction_->env() != NULL) {
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->pending_deoptimization_env_ = env;
|
||||
}
|
||||
__ Push(locs->in(0).reg());
|
||||
__ Push(locs->in(1).reg());
|
||||
compiler->EmitMegamorphicInstanceCall(
|
||||
@@ -2979,7 +2973,6 @@ class CheckedSmiSlowPath : public SlowPathCode {
|
||||
__ mov(result, V0);
|
||||
compiler->RestoreLiveRegisters(locs);
|
||||
__ b(exit_label());
|
||||
compiler->pending_deoptimization_env_ = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -3101,10 +3094,6 @@ class CheckedSmiComparisonSlowPath : public SlowPathCode {
|
||||
locs->live_registers()->Remove(Location::RegisterLocation(result));
|
||||
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
if (instruction_->env() != NULL) {
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->pending_deoptimization_env_ = env;
|
||||
}
|
||||
__ Push(locs->in(0).reg());
|
||||
__ Push(locs->in(1).reg());
|
||||
compiler->EmitMegamorphicInstanceCall(
|
||||
@@ -3114,7 +3103,6 @@ class CheckedSmiComparisonSlowPath : public SlowPathCode {
|
||||
/* slow_path_argument_count = */ 2);
|
||||
__ mov(result, V0);
|
||||
compiler->RestoreLiveRegisters(locs);
|
||||
compiler->pending_deoptimization_env_ = NULL;
|
||||
if (merged_) {
|
||||
__ BranchEqual(result, Bool::True(), instruction_->is_negated()
|
||||
? labels_.false_label
|
||||
@@ -5143,15 +5131,12 @@ class RangeErrorSlowPath : public SlowPathCode {
|
||||
}
|
||||
__ Bind(entry_label());
|
||||
LocationSummary* locs = instruction_->locs();
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
__ Push(locs->in(0).reg());
|
||||
__ Push(locs->in(1).reg());
|
||||
__ CallRuntime(kRangeErrorRuntimeEntry, 2);
|
||||
compiler->AddDescriptor(
|
||||
RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
|
||||
instruction_->deopt_id(), instruction_->token_pos(), try_index_);
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->EmitCatchEntryState(env, try_index_);
|
||||
__ break_(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2151,9 +2151,8 @@ void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
const Code& stub = Code::ZoneHandle(compiler->zone(),
|
||||
StubCode::AllocateArray_entry()->code());
|
||||
compiler->AddStubCallTarget(stub);
|
||||
compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
|
||||
*StubCode::AllocateArray_entry(),
|
||||
RawPcDescriptors::kOther, locs());
|
||||
compiler->GenerateCall(token_pos(), *StubCode::AllocateArray_entry(),
|
||||
RawPcDescriptors::kOther, locs());
|
||||
__ Bind(&done);
|
||||
ASSERT(locs()->out(0).reg() == kResultReg);
|
||||
}
|
||||
@@ -2830,10 +2829,6 @@ class CheckedSmiSlowPath : public SlowPathCode {
|
||||
locs->live_registers()->Remove(Location::RegisterLocation(result));
|
||||
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
if (instruction_->env() != NULL) {
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->pending_deoptimization_env_ = env;
|
||||
}
|
||||
__ pushq(locs->in(0).reg());
|
||||
__ pushq(locs->in(1).reg());
|
||||
compiler->EmitMegamorphicInstanceCall(
|
||||
@@ -2844,7 +2839,6 @@ class CheckedSmiSlowPath : public SlowPathCode {
|
||||
__ MoveRegister(result, RAX);
|
||||
compiler->RestoreLiveRegisters(locs);
|
||||
__ jmp(exit_label());
|
||||
compiler->pending_deoptimization_env_ = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -2995,10 +2989,6 @@ class CheckedSmiComparisonSlowPath : public SlowPathCode {
|
||||
locs->live_registers()->Remove(Location::RegisterLocation(result));
|
||||
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
if (instruction_->env() != NULL) {
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->pending_deoptimization_env_ = env;
|
||||
}
|
||||
__ pushq(locs->in(0).reg());
|
||||
__ pushq(locs->in(1).reg());
|
||||
compiler->EmitMegamorphicInstanceCall(
|
||||
@@ -3008,7 +2998,6 @@ class CheckedSmiComparisonSlowPath : public SlowPathCode {
|
||||
/* slow_path_argument_count = */ 2);
|
||||
__ MoveRegister(result, RAX);
|
||||
compiler->RestoreLiveRegisters(locs);
|
||||
compiler->pending_deoptimization_env_ = NULL;
|
||||
if (merged_) {
|
||||
__ CompareObject(result, Bool::True());
|
||||
__ j(EQUAL, instruction_->is_negated() ? labels_.false_label
|
||||
@@ -5918,7 +5907,6 @@ class RangeErrorSlowPath : public SlowPathCode {
|
||||
}
|
||||
__ Bind(entry_label());
|
||||
LocationSummary* locs = instruction_->locs();
|
||||
compiler->SaveLiveRegisters(locs);
|
||||
__ pushq(locs->in(0).reg());
|
||||
__ pushq(locs->in(1).reg());
|
||||
__ CallRuntime(kRangeErrorRuntimeEntry, 2);
|
||||
@@ -5926,8 +5914,6 @@ class RangeErrorSlowPath : public SlowPathCode {
|
||||
RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
|
||||
instruction_->deopt_id(), instruction_->token_pos(), try_index_);
|
||||
compiler->RecordSafepoint(locs, 2);
|
||||
Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
|
||||
compiler->EmitCatchEntryState(env, try_index_);
|
||||
__ int3();
|
||||
}
|
||||
|
||||
@@ -5941,6 +5927,7 @@ void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
RangeErrorSlowPath* slow_path =
|
||||
new RangeErrorSlowPath(this, compiler->CurrentTryIndex());
|
||||
compiler->AddSlowPathCode(slow_path);
|
||||
|
||||
Location length_loc = locs()->in(kLengthPos);
|
||||
Location index_loc = locs()->in(kIndexPos);
|
||||
Register length = length_loc.reg();
|
||||
@@ -6681,7 +6668,6 @@ void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
__ xorq(RBX, RBX);
|
||||
__ call(RCX);
|
||||
compiler->RecordSafepoint(locs());
|
||||
compiler->EmitCatchEntryState();
|
||||
// Marks either the continuation point in unoptimized code or the
|
||||
// deoptimization point in optimized code, after call.
|
||||
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
|
||||
|
||||
@@ -769,12 +769,6 @@ void BaseIsolate::AssertCurrentThreadIsMutator() const {
|
||||
|
||||
#define REUSABLE_HANDLE_INITIALIZERS(object) object##_handle_(NULL),
|
||||
|
||||
|
||||
static void FreeCatchEntryState(CatchEntryState* state) {
|
||||
delete state->data;
|
||||
}
|
||||
|
||||
|
||||
// TODO(srdjan): Some Isolate monitors can be shared. Replace their usage with
|
||||
// that shared monitor.
|
||||
Isolate::Isolate(const Dart_IsolateFlags& api_flags)
|
||||
@@ -852,8 +846,7 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
|
||||
reload_context_(NULL),
|
||||
last_reload_timestamp_(OS::GetCurrentTimeMillis()),
|
||||
should_pause_post_service_request_(false),
|
||||
handler_info_cache_(),
|
||||
catch_entry_state_cache_(FreeCatchEntryState) {
|
||||
handler_info_cache_() {
|
||||
NOT_IN_PRODUCT(FlagsCopyFrom(api_flags));
|
||||
// TODO(asiva): A Thread is not available here, need to figure out
|
||||
// how the vm_tag (kEmbedderTagId) can be set, these tags need to
|
||||
|
||||
@@ -128,8 +128,6 @@ class NoReloadScope : public StackResource {
|
||||
|
||||
// Fixed cache for exception handler lookup.
|
||||
typedef FixedCache<intptr_t, ExceptionHandlerInfo, 16> HandlerInfoCache;
|
||||
// Fixed cache for catch entry state lookup.
|
||||
typedef FixedCache<intptr_t, CatchEntryState, 16> CatchEntryStateCache;
|
||||
|
||||
// List of Isolate flags with corresponding members of Dart_IsolateFlags and
|
||||
// corresponding global command line flags.
|
||||
@@ -677,10 +675,6 @@ class Isolate : public BaseIsolate {
|
||||
|
||||
HandlerInfoCache* handler_info_cache() { return &handler_info_cache_; }
|
||||
|
||||
CatchEntryStateCache* catch_entry_state_cache() {
|
||||
return &catch_entry_state_cache_;
|
||||
}
|
||||
|
||||
void MaybeIncreaseReloadEveryNStackOverflowChecks();
|
||||
|
||||
private:
|
||||
@@ -876,7 +870,6 @@ class Isolate : public BaseIsolate {
|
||||
bool should_pause_post_service_request_;
|
||||
|
||||
HandlerInfoCache handler_info_cache_;
|
||||
CatchEntryStateCache catch_entry_state_cache_;
|
||||
|
||||
static Dart_IsolateCreateCallback create_callback_;
|
||||
static Dart_IsolateShutdownCallback shutdown_callback_;
|
||||
|
||||
@@ -14007,17 +14007,6 @@ void Code::set_stackmaps(const Array& maps) const {
|
||||
}
|
||||
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER)
|
||||
void Code::set_variables(const Smi& smi) const {
|
||||
StorePointer(&raw_ptr()->catch_entry_.variables_, smi.raw());
|
||||
}
|
||||
#else
|
||||
void Code::set_catch_entry_state_maps(const TypedData& maps) const {
|
||||
StorePointer(&raw_ptr()->catch_entry_.catch_entry_state_maps_, maps.raw());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Code::set_deopt_info_array(const Array& array) const {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
UNREACHABLE();
|
||||
|
||||
@@ -4708,16 +4708,6 @@ class Code : public Object {
|
||||
}
|
||||
void set_deopt_info_array(const Array& array) const;
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER)
|
||||
RawSmi* variables() const { return raw_ptr()->catch_entry_.variables_; }
|
||||
void set_variables(const Smi& smi) const;
|
||||
#else
|
||||
RawTypedData* catch_entry_state_maps() const {
|
||||
return raw_ptr()->catch_entry_.catch_entry_state_maps_;
|
||||
}
|
||||
void set_catch_entry_state_maps(const TypedData& maps) const;
|
||||
#endif
|
||||
|
||||
RawArray* stackmaps() const { return raw_ptr()->stackmaps_; }
|
||||
void set_stackmaps(const Array& maps) const;
|
||||
RawStackMap* GetStackMap(uint32_t pc_offset,
|
||||
|
||||
@@ -2931,7 +2931,6 @@ void PrecompileParsedFunctionHelper::FinalizeCompilation(
|
||||
graph_compiler->FinalizeStackMaps(code);
|
||||
graph_compiler->FinalizeVarDescriptors(code);
|
||||
graph_compiler->FinalizeExceptionHandlers(code);
|
||||
graph_compiler->FinalizeCatchEntryStateMap(code);
|
||||
graph_compiler->FinalizeStaticCallTargetsTable(code);
|
||||
graph_compiler->FinalizeCodeSourceMap(code);
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "platform/assert.h"
|
||||
#include "vm/atomic.h"
|
||||
#include "vm/exceptions.h"
|
||||
#include "vm/globals.h"
|
||||
#include "vm/snapshot.h"
|
||||
#include "vm/token.h"
|
||||
@@ -1139,10 +1138,6 @@ class RawCode : public RawObject {
|
||||
RawObject* owner_; // Function, Null, or a Class.
|
||||
RawExceptionHandlers* exception_handlers_;
|
||||
RawPcDescriptors* pc_descriptors_;
|
||||
union {
|
||||
RawTypedData* catch_entry_state_maps_;
|
||||
RawSmi* variables_;
|
||||
} catch_entry_;
|
||||
RawArray* stackmaps_;
|
||||
RawArray* inlined_id_to_function_;
|
||||
RawCodeSourceMap* code_source_map_;
|
||||
|
||||
@@ -250,15 +250,13 @@ RawCode* StackFrame::GetCodeObject() const {
|
||||
bool StackFrame::FindExceptionHandler(Thread* thread,
|
||||
uword* handler_pc,
|
||||
bool* needs_stacktrace,
|
||||
bool* has_catch_all,
|
||||
bool* is_optimized) const {
|
||||
bool* has_catch_all) const {
|
||||
REUSABLE_CODE_HANDLESCOPE(thread);
|
||||
Code& code = reused_code_handle.Handle();
|
||||
code = LookupDartCode();
|
||||
if (code.IsNull()) {
|
||||
return false; // Stub frames do not have exception handlers.
|
||||
}
|
||||
*is_optimized = code.is_optimized();
|
||||
HandlerInfoCache* cache = thread->isolate()->handler_info_cache();
|
||||
ExceptionHandlerInfo* info = cache->Lookup(pc());
|
||||
if (info != NULL) {
|
||||
|
||||
@@ -101,8 +101,7 @@ class StackFrame : public ValueObject {
|
||||
bool FindExceptionHandler(Thread* thread,
|
||||
uword* handler_pc,
|
||||
bool* needs_stacktrace,
|
||||
bool* is_catch_all,
|
||||
bool* is_optimized) const;
|
||||
bool* is_catch_all) const;
|
||||
// Returns token_pos of the pc(), or -1 if none exists.
|
||||
TokenPosition GetTokenPos() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user