Revision: 23334
Author: [email protected]
Date: Mon Aug 25 07:02:19 2014 UTC
Log: Fix deoptimization address patching in Turbofan to use safepoints.
Since the deopt patch address needs to be available during GC to
resolve safepoints, we need to move it to the code object (instead of
the deoptimization input data) - accessing a separate fixed array
is not safe during GC. This CL adds a deoptimization_pc field to
each safepoint. The fields points to the deoptimization block.
The CL also fixes wrong register allocator constraints for
frame states on calls. These should always live on the stack
because registers are not preserved during a call.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/504493002
https://code.google.com/p/v8/source/detail?r=23334
Modified:
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc
/branches/bleeding_edge/src/compiler/code-generator.cc
/branches/bleeding_edge/src/compiler/code-generator.h
/branches/bleeding_edge/src/compiler/instruction-selector.cc
/branches/bleeding_edge/src/deoptimizer.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
/branches/bleeding_edge/src/mips64/lithium-codegen-mips64.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/safepoint-table.cc
/branches/bleeding_edge/src/safepoint-table.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x87/lithium-codegen-x87.cc
/branches/bleeding_edge/test/cctest/compiler/test-codegen-deopt.cc
/branches/bleeding_edge/test/mjsunit/mjsunit.status
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Aug 22
11:43:39 2014 UTC
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Aug 25
07:02:19 2014 UTC
@@ -931,7 +931,7 @@
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
=======================================
--- /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Fri Aug 22
11:43:39 2014 UTC
+++ /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Mon Aug 25
07:02:19 2014 UTC
@@ -937,7 +937,7 @@
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
=======================================
--- /branches/bleeding_edge/src/compiler/code-generator.cc Thu Aug 21
11:56:46 2014 UTC
+++ /branches/bleeding_edge/src/compiler/code-generator.cc Mon Aug 25
07:02:19 2014 UTC
@@ -53,6 +53,7 @@
FinishCode(masm());
+ UpdateSafepointsWithDeoptimizationPc();
safepoints()->Emit(masm(), frame()->GetSpillSlotCount());
// TODO(titzer): what are the right code flags here?
@@ -76,9 +77,10 @@
}
-void CodeGenerator::RecordSafepoint(PointerMap* pointers, Safepoint::Kind
kind,
- int arguments,
- Safepoint::DeoptMode deopt_mode) {
+Safepoint::Id CodeGenerator::RecordSafepoint(PointerMap* pointers,
+ Safepoint::Kind kind,
+ int arguments,
+ Safepoint::DeoptMode
deopt_mode) {
const ZoneList<InstructionOperand*>* operands =
pointers->GetNormalizedOperands();
Safepoint safepoint =
@@ -92,6 +94,7 @@
safepoint.DefinePointerRegister(reg, zone());
}
}
+ return safepoint.id();
}
@@ -170,6 +173,18 @@
if (move != NULL) resolver()->Resolve(move);
}
}
+
+
+void CodeGenerator::UpdateSafepointsWithDeoptimizationPc() {
+ int patch_count = static_cast<int>(lazy_deoptimization_entries_.size());
+ for (int i = 0; i < patch_count; ++i) {
+ LazyDeoptimizationEntry entry = lazy_deoptimization_entries_[i];
+ // TODO(jarin) make sure that there is no code (other than nops)
+ // between the call position and the continuation position.
+ safepoints()->SetDeoptimizationPc(entry.safepoint_id(),
+ entry.deoptimization()->pos());
+ }
+}
void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
@@ -177,8 +192,8 @@
int deopt_count = code()->GetDeoptimizationEntryCount();
int patch_count = static_cast<int>(lazy_deoptimization_entries_.size());
if (patch_count == 0 && deopt_count == 0) return;
- Handle<DeoptimizationInputData> data = DeoptimizationInputData::New(
- isolate(), deopt_count, patch_count, TENURED);
+ Handle<DeoptimizationInputData> data =
+ DeoptimizationInputData::New(isolate(), deopt_count, TENURED);
Handle<ByteArray> translation_array =
translations_.CreateByteArray(isolate()->factory());
@@ -221,13 +236,6 @@
data->SetArgumentsStackHeight(i, Smi::FromInt(0));
data->SetPc(i, Smi::FromInt(-1));
}
-
- // Populate the return address patcher entries.
- for (int i = 0; i < patch_count; ++i) {
- LazyDeoptimizationEntry entry = lazy_deoptimization_entries_[i];
- data->SetReturnAddressPc(i, Smi::FromInt(entry.position_after_call()));
- data->SetPatchedAddressPc(i,
Smi::FromInt(entry.deoptimization()->pos()));
- }
code_object->set_deoptimization_data(*data);
}
@@ -238,30 +246,43 @@
static_cast<CallDescriptor::DeoptimizationSupport>(
MiscField::decode(instr->opcode()));
- if ((deopt & CallDescriptor::kLazyDeoptimization) != 0) {
- RecordLazyDeoptimizationEntry(instr);
- }
-
bool needs_frame_state = (deopt & CallDescriptor::kNeedsFrameState) != 0;
- RecordSafepoint(
+ Safepoint::Id safepoint_id = RecordSafepoint(
instr->pointer_map(), Safepoint::kSimple, 0,
needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt);
- if ((deopt & CallDescriptor::kNeedsFrameState) != 0) {
+ if ((deopt & CallDescriptor::kLazyDeoptimization) != 0) {
+ RecordLazyDeoptimizationEntry(instr, safepoint_id);
+ }
+
+ if (needs_frame_state) {
// If the frame state is present, it starts at argument 1
// (just after the code address).
InstructionOperandConverter converter(this, instr);
// Argument 1 is deoptimization id.
int deoptimization_id =
converter.ToConstant(instr->InputAt(1)).ToInt32();
// The actual frame state values start with argument 2.
- BuildTranslation(instr, 2, deoptimization_id);
+ int first_state_value_offset = 2;
+#if DEBUG
+ // Make sure all the values live in stack slots or they are immediates.
+ // (The values should not live in register because registers are
clobbered
+ // by calls.)
+ FrameStateDescriptor* descriptor =
+ code()->GetDeoptimizationEntry(deoptimization_id);
+ for (int i = 0; i < descriptor->size(); i++) {
+ InstructionOperand* op = instr->InputAt(first_state_value_offset +
i);
+ CHECK(op->IsStackSlot() || op->IsImmediate());
+ }
+#endif
+ BuildTranslation(instr, first_state_value_offset, deoptimization_id);
safepoints()->RecordLazyDeoptimizationIndex(deoptimization_id);
}
}
-void CodeGenerator::RecordLazyDeoptimizationEntry(Instruction* instr) {
+void CodeGenerator::RecordLazyDeoptimizationEntry(Instruction* instr,
+ Safepoint::Id
safepoint_id) {
InstructionOperandConverter i(this, instr);
Label after_call;
@@ -276,8 +297,8 @@
Label* cont_label = code_->GetLabel(cont_block);
Label* deopt_label = code_->GetLabel(deopt_block);
- lazy_deoptimization_entries_.push_back(
- LazyDeoptimizationEntry(after_call.pos(), cont_label, deopt_label));
+ lazy_deoptimization_entries_.push_back(LazyDeoptimizationEntry(
+ after_call.pos(), cont_label, deopt_label, safepoint_id));
}
=======================================
--- /branches/bleeding_edge/src/compiler/code-generator.h Thu Aug 21
11:56:46 2014 UTC
+++ /branches/bleeding_edge/src/compiler/code-generator.h Mon Aug 25
07:02:19 2014 UTC
@@ -46,8 +46,8 @@
}
// Record a safepoint with the given pointer map.
- void RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
- int arguments, Safepoint::DeoptMode deopt_mode);
+ Safepoint::Id RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
+ int arguments, Safepoint::DeoptMode
deopt_mode);
// Assemble code for the specified instruction.
void AssembleInstruction(Instruction* instr);
@@ -82,7 +82,9 @@
//
===========================================================================
// Deoptimization table construction
void AddSafepointAndDeopt(Instruction* instr);
- void RecordLazyDeoptimizationEntry(Instruction* instr);
+ void UpdateSafepointsWithDeoptimizationPc();
+ void RecordLazyDeoptimizationEntry(Instruction* instr,
+ Safepoint::Id safepoint_id);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
void BuildTranslation(Instruction* instr, int first_argument_index,
@@ -95,19 +97,22 @@
class LazyDeoptimizationEntry V8_FINAL {
public:
LazyDeoptimizationEntry(int position_after_call, Label* continuation,
- Label* deoptimization)
+ Label* deoptimization, Safepoint::Id
safepoint_id)
: position_after_call_(position_after_call),
continuation_(continuation),
- deoptimization_(deoptimization) {}
+ deoptimization_(deoptimization),
+ safepoint_id_(safepoint_id) {}
int position_after_call() const { return position_after_call_; }
Label* continuation() const { return continuation_; }
Label* deoptimization() const { return deoptimization_; }
+ Safepoint::Id safepoint_id() const { return safepoint_id_; }
private:
int position_after_call_;
Label* continuation_;
Label* deoptimization_;
+ Safepoint::Id safepoint_id_;
};
struct DeoptimizationState : ZoneObject {
=======================================
--- /branches/bleeding_edge/src/compiler/instruction-selector.cc Thu Aug 21
12:02:24 2014 UTC
+++ /branches/bleeding_edge/src/compiler/instruction-selector.cc Mon Aug 25
07:02:19 2014 UTC
@@ -1039,7 +1039,7 @@
case IrOpcode::kHeapConstant:
return g->UseImmediate(input);
default:
- return g->Use(input);
+ return g->UseUnique(input);
}
}
=======================================
--- /branches/bleeding_edge/src/deoptimizer.cc Fri Aug 22 07:44:18 2014 UTC
+++ /branches/bleeding_edge/src/deoptimizer.cc Mon Aug 25 07:02:19 2014 UTC
@@ -440,23 +440,6 @@
}
}
}
-
-
-static int FindPatchAddressForReturnAddress(Code* code, int pc) {
- DeoptimizationInputData* input_data =
- DeoptimizationInputData::cast(code->deoptimization_data());
- int patch_count = input_data->ReturnAddressPatchCount();
- for (int i = 0; i < patch_count; i++) {
- int return_pc = input_data->ReturnAddressPc(i)->value();
- int patch_pc = input_data->PatchedAddressPc(i)->value();
- // If the supplied pc matches the return pc or if the address
- // has been already patched, return the patch pc.
- if (pc == return_pc || pc == patch_pc) {
- return patch_pc;
- }
- }
- return -1;
-}
// For all marked Turbofanned code on stack, change the return address to
go
@@ -474,7 +457,8 @@
Address* pc_address = it.frame()->pc_address();
int pc_offset =
static_cast<int>(*pc_address - code->instruction_start());
- int new_pc_offset = FindPatchAddressForReturnAddress(code,
pc_offset);
+ SafepointEntry safepoint_entry =
code->GetSafepointEntry(*pc_address);
+ unsigned new_pc_offset = safepoint_entry.deoptimization_pc();
if (FLAG_trace_deopt) {
CodeTracer::Scope scope(isolate->GetCodeTracer());
@@ -484,8 +468,8 @@
new_pc_offset);
}
- CHECK_LE(0, new_pc_offset);
- *pc_address += new_pc_offset - pc_offset;
+ CHECK(new_pc_offset != Safepoint::kNoDeoptimizationPc);
+ *pc_address += static_cast<int>(new_pc_offset) - pc_offset;
}
}
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Aug 22
11:43:39 2014 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Aug 25
07:02:19 2014 UTC
@@ -900,7 +900,7 @@
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Mon Aug 18
07:54:19 2014 UTC
+++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Mon Aug 25
07:02:19 2014 UTC
@@ -897,7 +897,7 @@
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
=======================================
--- /branches/bleeding_edge/src/mips64/lithium-codegen-mips64.cc Mon Aug 18
07:54:19 2014 UTC
+++ /branches/bleeding_edge/src/mips64/lithium-codegen-mips64.cc Mon Aug 25
07:02:19 2014 UTC
@@ -852,7 +852,7 @@
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Tue Aug 19 08:53:38 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h Mon Aug 25 07:02:19 2014 UTC
@@ -717,19 +717,9 @@
// the entry size.
int length = FixedArray::cast(this)->length();
if (length == 0) return true;
- if (length < DeoptimizationInputData::kFirstDeoptEntryIndex) return
false;
- FixedArray* self = FixedArray::cast(const_cast<Object*>(this));
- int deopt_count =
- Smi::cast(self->get(DeoptimizationInputData::kDeoptEntryCountIndex))
- ->value();
- int patch_count =
- Smi::cast(
- self->get(
- DeoptimizationInputData::kReturnAddressPatchEntryCountIndex))
- ->value();
-
- return length == DeoptimizationInputData::LengthFor(deopt_count,
patch_count);
+ length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
+ return length >= 0 && length % DeoptimizationInputData::kDeoptEntrySize
== 0;
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Fri Aug 22 11:48:52 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Mon Aug 25 07:02:19 2014 UTC
@@ -7933,17 +7933,11 @@
Handle<DeoptimizationInputData> DeoptimizationInputData::New(
- Isolate* isolate, int deopt_entry_count, int
return_patch_address_count,
- PretenureFlag pretenure) {
- DCHECK(deopt_entry_count + return_patch_address_count > 0);
- Handle<FixedArray> deoptimization_data =
- Handle<FixedArray>::cast(isolate->factory()->NewFixedArray(
- LengthFor(deopt_entry_count, return_patch_address_count),
pretenure));
- deoptimization_data->set(kDeoptEntryCountIndex,
- Smi::FromInt(deopt_entry_count));
- deoptimization_data->set(kReturnAddressPatchEntryCountIndex,
- Smi::FromInt(return_patch_address_count));
- return Handle<DeoptimizationInputData>::cast(deoptimization_data);
+ Isolate* isolate, int deopt_entry_count, PretenureFlag pretenure) {
+ DCHECK(deopt_entry_count > 0);
+ return Handle<DeoptimizationInputData>::cast(
+ isolate->factory()->NewFixedArray(LengthFor(deopt_entry_count),
+ pretenure));
}
@@ -10291,26 +10285,7 @@
SafepointEntry Code::GetSafepointEntry(Address pc) {
SafepointTable table(this);
- SafepointEntry entry = table.FindEntry(pc);
- if (entry.is_valid() || !is_turbofanned()) {
- return entry;
- }
-
- // If the code is turbofanned, we might be looking for
- // an address that was patched by lazy deoptimization.
- // In that case look through the patch table, try to
- // lookup the original address there, and then use this
- // to find the safepoint entry.
- DeoptimizationInputData* deopt_data =
- DeoptimizationInputData::cast(deoptimization_data());
- intptr_t offset = pc - instruction_start();
- for (int i = 0; i < deopt_data->ReturnAddressPatchCount(); i++) {
- if (deopt_data->PatchedAddressPc(i)->value() == offset) {
- int original_offset = deopt_data->ReturnAddressPc(i)->value();
- return table.FindEntry(instruction_start() + original_offset);
- }
- }
- return SafepointEntry();
+ return table.FindEntry(pc);
}
@@ -10863,19 +10838,6 @@
os << "\n";
}
}
-
- int return_address_patch_count = ReturnAddressPatchCount();
- if (return_address_patch_count != 0) {
- os << "Return address patch data (count = " <<
return_address_patch_count
- << ")\n";
- os << " index pc patched_pc\n";
- }
- for (int i = 0; i < return_address_patch_count; i++) {
- Vector<char> buf = Vector<char>::New(128);
- SNPrintF(buf, "%6d %6d %12d\n", i, ReturnAddressPc(i)->value(),
- PatchedAddressPc(i)->value());
- os << buf.start();
- }
}
@@ -11006,6 +10968,13 @@
} else {
os << "<none>";
}
+ if (entry.deoptimization_pc() != Safepoint::kNoDeoptimizationPc) {
+ Vector<char> buf2 = Vector<char>::New(30);
+ SNPrintF(buf2, "%6d", entry.deoptimization_pc());
+ os << buf2.start();
+ } else {
+ os << "<none>";
+ }
if (entry.argument_count() > 0) {
os << " argc: " << entry.argument_count();
}
=======================================
--- /branches/bleeding_edge/src/objects.h Fri Aug 22 11:48:52 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Mon Aug 25 07:02:19 2014 UTC
@@ -5151,16 +5151,14 @@
class DeoptimizationInputData: public FixedArray {
public:
// Layout description. Indices in the array.
- static const int kDeoptEntryCountIndex = 0;
- static const int kReturnAddressPatchEntryCountIndex = 1;
- static const int kTranslationByteArrayIndex = 2;
- static const int kInlinedFunctionCountIndex = 3;
- static const int kLiteralArrayIndex = 4;
- static const int kOsrAstIdIndex = 5;
- static const int kOsrPcOffsetIndex = 6;
- static const int kOptimizationIdIndex = 7;
- static const int kSharedFunctionInfoIndex = 8;
- static const int kFirstDeoptEntryIndex = 9;
+ static const int kTranslationByteArrayIndex = 0;
+ static const int kInlinedFunctionCountIndex = 1;
+ static const int kLiteralArrayIndex = 2;
+ static const int kOsrAstIdIndex = 3;
+ static const int kOsrPcOffsetIndex = 4;
+ static const int kOptimizationIdIndex = 5;
+ static const int kSharedFunctionInfoIndex = 6;
+ static const int kFirstDeoptEntryIndex = 7;
// Offsets of deopt entry elements relative to the start of the entry.
static const int kAstIdRawOffset = 0;
@@ -5169,12 +5167,6 @@
static const int kPcOffset = 3;
static const int kDeoptEntrySize = 4;
- // Offsets of return address patch entry elements relative to the start
of the
- // entry
- static const int kReturnAddressPcOffset = 0;
- static const int kPatchedAddressPcOffset = 1;
- static const int kReturnAddressPatchEntrySize = 2;
-
// Simple element accessors.
#define DEFINE_ELEMENT_ACCESSORS(name, type) \
type* name() { \
@@ -5195,7 +5187,7 @@
#undef DEFINE_ELEMENT_ACCESSORS
// Accessors for elements of the ith deoptimization entry.
-#define DEFINE_DEOPT_ENTRY_ACCESSORS(name, type) \
+#define DEFINE_ENTRY_ACCESSORS(name, type) \
type* name(int i) { \
return type::cast(get(IndexForEntry(i) + k##name##Offset)); \
} \
@@ -5203,28 +5195,13 @@
set(IndexForEntry(i) + k##name##Offset, value); \
}
- DEFINE_DEOPT_ENTRY_ACCESSORS(AstIdRaw, Smi)
- DEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi)
- DEFINE_DEOPT_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
- DEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi)
+ DEFINE_ENTRY_ACCESSORS(AstIdRaw, Smi)
+ DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi)
+ DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi)
+ DEFINE_ENTRY_ACCESSORS(Pc, Smi)
#undef DEFINE_DEOPT_ENTRY_ACCESSORS
-// Accessors for elements of the ith deoptimization entry.
-#define DEFINE_PATCH_ENTRY_ACCESSORS(name, type) \
- type* name(int i) { \
- return type::cast( \
- get(IndexForReturnAddressPatchEntry(i) + k##name##Offset)); \
- } \
- void Set##name(int i, type* value) { \
- set(IndexForReturnAddressPatchEntry(i) + k##name##Offset, value); \
- }
-
- DEFINE_PATCH_ENTRY_ACCESSORS(ReturnAddressPc, Smi)
- DEFINE_PATCH_ENTRY_ACCESSORS(PatchedAddressPc, Smi)
-
-#undef DEFINE_PATCH_ENTRY_ACCESSORS
-
BailoutId AstId(int i) {
return BailoutId(AstIdRaw(i)->value());
}
@@ -5234,19 +5211,12 @@
}
int DeoptCount() {
- return length() == 0 ? 0 :
Smi::cast(get(kDeoptEntryCountIndex))->value();
- }
-
- int ReturnAddressPatchCount() {
- return length() == 0
- ? 0
- :
Smi::cast(get(kReturnAddressPatchEntryCountIndex))->value();
+ return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize;
}
// Allocates a DeoptimizationInputData.
static Handle<DeoptimizationInputData> New(Isolate* isolate,
int deopt_entry_count,
- int
return_address_patch_count,
PretenureFlag pretenure);
DECLARE_CAST(DeoptimizationInputData)
@@ -5256,21 +5226,12 @@
#endif
private:
- friend class Object; // For accessing LengthFor.
-
static int IndexForEntry(int i) {
return kFirstDeoptEntryIndex + (i * kDeoptEntrySize);
}
- int IndexForReturnAddressPatchEntry(int i) {
- return kFirstDeoptEntryIndex + (DeoptCount() * kDeoptEntrySize) +
- (i * kReturnAddressPatchEntrySize);
- }
- static int LengthFor(int deopt_count, int return_address_patch_count) {
- return kFirstDeoptEntryIndex + (deopt_count * kDeoptEntrySize) +
- (return_address_patch_count * kReturnAddressPatchEntrySize);
- }
+ static int LengthFor(int entry_count) { return
IndexForEntry(entry_count); }
};
=======================================
--- /branches/bleeding_edge/src/safepoint-table.cc Mon Aug 4 11:34:54 2014
UTC
+++ /branches/bleeding_edge/src/safepoint-table.cc Mon Aug 25 07:02:19 2014
UTC
@@ -43,8 +43,8 @@
length_ = Memory::uint32_at(header + kLengthOffset);
entry_size_ = Memory::uint32_at(header + kEntrySizeOffset);
pc_and_deoptimization_indexes_ = header + kHeaderSize;
- entries_ = pc_and_deoptimization_indexes_ +
- (length_ * kPcAndDeoptimizationIndexSize);
+ entries_ =
+ pc_and_deoptimization_indexes_ + (length_ *
kPcAndDeoptimizationInfoSize);
DCHECK(entry_size_ > 0);
STATIC_ASSERT(SafepointEntry::DeoptimizationIndexField::kMax ==
Safepoint::kNoDeoptimizationIndex);
@@ -56,6 +56,7 @@
for (unsigned i = 0; i < length(); i++) {
// TODO(kasperl): Replace the linear search with binary search.
if (GetPcOffset(i) == pc_offset) return GetEntry(i);
+ if (GetDeoptimizationPcOffset(i) == pc_offset) return GetEntry(i);
}
return SafepointEntry();
}
@@ -110,6 +111,8 @@
info.pc = assembler->pc_offset();
info.arguments = arguments;
info.has_doubles = (kind & Safepoint::kWithDoubles);
+ info.deoptimization_pc = Safepoint::kNoDeoptimizationPc;
+ int safepoint_id = deoptimization_info_.length();
deoptimization_info_.Add(info, zone_);
deopt_index_list_.Add(Safepoint::kNoDeoptimizationIndex, zone_);
if (deopt_mode == Safepoint::kNoLazyDeopt) {
@@ -120,7 +123,7 @@
? new(zone_) ZoneList<int>(4, zone_)
: NULL,
zone_);
- return Safepoint(indexes_.last(), registers_.last());
+ return Safepoint(safepoint_id, indexes_.last(), registers_.last());
}
@@ -159,6 +162,7 @@
assembler->dd(deoptimization_info_[i].pc);
assembler->dd(EncodeExceptPC(deoptimization_info_[i],
deopt_index_list_[i]));
+ assembler->dd(deoptimization_info_[i].deoptimization_pc);
}
// Emit table of bitmaps.
=======================================
--- /branches/bleeding_edge/src/safepoint-table.h Tue Aug 5 08:18:22 2014
UTC
+++ /branches/bleeding_edge/src/safepoint-table.h Mon Aug 25 07:02:19 2014
UTC
@@ -17,9 +17,10 @@
class SafepointEntry BASE_EMBEDDED {
public:
- SafepointEntry() : info_(0), bits_(NULL) {}
+ SafepointEntry() : info_(0), deoptimization_pc_(0), bits_(NULL) {}
- SafepointEntry(unsigned info, uint8_t* bits) : info_(info), bits_(bits) {
+ SafepointEntry(unsigned info, unsigned deoptimization_pc, uint8_t* bits)
+ : info_(info), deoptimization_pc_(deoptimization_pc), bits_(bits) {
DCHECK(is_valid());
}
@@ -38,6 +39,11 @@
DCHECK(is_valid());
return DeoptimizationIndexField::decode(info_);
}
+
+ unsigned deoptimization_pc() const {
+ DCHECK(is_valid());
+ return deoptimization_pc_;
+ }
static const int kArgumentsFieldBits = 3;
static const int kSaveDoublesFieldBits = 1;
@@ -74,6 +80,7 @@
private:
unsigned info_;
+ unsigned deoptimization_pc_;
uint8_t* bits_;
};
@@ -84,7 +91,8 @@
int size() const {
return kHeaderSize +
- (length_ * (kPcAndDeoptimizationIndexSize + entry_size_)); }
+ (length_ * (kPcAndDeoptimizationInfoSize + entry_size_));
+ }
unsigned length() const { return length_; }
unsigned entry_size() const { return entry_size_; }
@@ -92,12 +100,18 @@
DCHECK(index < length_);
return Memory::uint32_at(GetPcOffsetLocation(index));
}
+
+ unsigned GetDeoptimizationPcOffset(unsigned index) const {
+ DCHECK(index < length_);
+ return Memory::uint32_at(GetDeoptimizationPcLocation(index));
+ }
SafepointEntry GetEntry(unsigned index) const {
DCHECK(index < length_);
unsigned info = Memory::uint32_at(GetInfoLocation(index));
+ unsigned deopt_pc =
Memory::uint32_at(GetDeoptimizationPcLocation(index));
uint8_t* bits = &Memory::uint8_at(entries_ + (index * entry_size_));
- return SafepointEntry(info, bits);
+ return SafepointEntry(info, deopt_pc, bits);
}
// Returns the entry for the given pc.
@@ -114,17 +128,22 @@
static const int kPcSize = kIntSize;
static const int kDeoptimizationIndexSize = kIntSize;
- static const int kPcAndDeoptimizationIndexSize =
- kPcSize + kDeoptimizationIndexSize;
+ static const int kDeoptimizationPcSize = kIntSize;
+ static const int kPcAndDeoptimizationInfoSize =
+ kPcSize + kDeoptimizationIndexSize + kDeoptimizationPcSize;
Address GetPcOffsetLocation(unsigned index) const {
return pc_and_deoptimization_indexes_ +
- (index * kPcAndDeoptimizationIndexSize);
+ (index * kPcAndDeoptimizationInfoSize);
}
Address GetInfoLocation(unsigned index) const {
return GetPcOffsetLocation(index) + kPcSize;
}
+
+ Address GetDeoptimizationPcLocation(unsigned index) const {
+ return GetInfoLocation(index) + kDeoptimizationIndexSize;
+ }
static void PrintBits(OStream& os, // NOLINT
uint8_t byte, int digits);
@@ -158,15 +177,30 @@
kLazyDeopt
};
+ class Id {
+ private:
+ explicit Id(int id) : id_(id) {}
+
+ int id_;
+
+ friend class SafepointTableBuilder;
+ friend class Safepoint;
+ };
+
static const int kNoDeoptimizationIndex =
(1 << (SafepointEntry::kDeoptIndexBits)) - 1;
+ static const unsigned kNoDeoptimizationPc = ~0U;
+
void DefinePointerSlot(int index, Zone* zone) { indexes_->Add(index,
zone); }
void DefinePointerRegister(Register reg, Zone* zone);
+
+ Id id() const { return Id(id_); }
private:
- Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers) :
- indexes_(indexes), registers_(registers) { }
+ Safepoint(int id, ZoneList<int>* indexes, ZoneList<int>* registers)
+ : id_(id), indexes_(indexes), registers_(registers) {}
+ int id_;
ZoneList<int>* indexes_;
ZoneList<int>* registers_;
@@ -200,6 +234,11 @@
void BumpLastLazySafepointIndex() {
last_lazy_safepoint_ = deopt_index_list_.length();
}
+ void SetDeoptimizationPc(Safepoint::Id safepoint_id,
+ unsigned deoptimization_pc) {
+ deoptimization_info_[safepoint_id.id_].deoptimization_pc =
+ deoptimization_pc;
+ }
// Emit the safepoint table after the body. The number of bits per
// entry must be enough to hold all the pointer indexes.
@@ -211,6 +250,7 @@
unsigned pc;
unsigned arguments;
bool has_doubles;
+ unsigned deoptimization_pc;
};
uint32_t EncodeExceptPC(const DeoptimizationInfo& info, unsigned index);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri Aug 22
11:43:39 2014 UTC
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Aug 25
07:02:19 2014 UTC
@@ -810,7 +810,7 @@
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
=======================================
--- /branches/bleeding_edge/src/x87/lithium-codegen-x87.cc Mon Aug 18
07:54:19 2014 UTC
+++ /branches/bleeding_edge/src/x87/lithium-codegen-x87.cc Mon Aug 25
07:02:19 2014 UTC
@@ -1095,7 +1095,7 @@
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- DeoptimizationInputData::New(isolate(), length, 0, TENURED);
+ DeoptimizationInputData::New(isolate(), length, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-codegen-deopt.cc Tue
Aug 19 11:24:24 2014 UTC
+++ /branches/bleeding_edge/test/cctest/compiler/test-codegen-deopt.cc Mon
Aug 25 07:02:19 2014 UTC
@@ -201,11 +201,12 @@
Label* cont_label = t.code->GetLabel(t.cont_block);
Label* deopt_label = t.code->GetLabel(t.deopt_block);
- // Check the patch table. It should patch the continuation address to the
- // deoptimization block address.
- CHECK_EQ(1, data->ReturnAddressPatchCount());
- CHECK_EQ(cont_label->pos(), data->ReturnAddressPc(0)->value());
- CHECK_EQ(deopt_label->pos(), data->PatchedAddressPc(0)->value());
+ // Check the safepoint - it should contain an entry for the call
+ // with the right deoptimization address.
+ SafepointEntry entry = t.result_code->GetSafepointEntry(
+ t.result_code->instruction_start() + cont_label->pos());
+ CHECK(entry.is_valid());
+ CHECK_EQ(deopt_label->pos(), entry.deoptimization_pc());
// Check that we deoptimize to the right AST id.
CHECK_EQ(1, data->DeoptCount());
=======================================
--- /branches/bleeding_edge/test/mjsunit/mjsunit.status Fri Aug 22 09:54:01
2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/mjsunit.status Mon Aug 25 07:02:19
2014 UTC
@@ -97,8 +97,6 @@
'deserialize-reference': [PASS, NO_VARIANTS],
# Support for %GetFrameDetails is missing and requires checkpoints.
- 'debug-backtrace-text': [PASS, NO_VARIANTS],
- 'debug-break-inline': [PASS, NO_VARIANTS],
'debug-evaluate-bool-constructor': [PASS, NO_VARIANTS],
'debug-evaluate-closure': [PASS, NO_VARIANTS],
'debug-evaluate-const': [PASS, NO_VARIANTS],
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.