Revision: 21165
Author: [email protected]
Date: Tue May 6 11:25:37 2014 UTC
Log: Fix for 3303 MultithreadedParallelIsolates has a race condition.
The fix is to make the code aging sequence hang off the isolate.
BUG=v8:3303
[email protected]
LOG=N
Review URL: https://codereview.chromium.org/261953002
http://code.google.com/p/v8/source/detail?r=21165
Modified:
/branches/bleeding_edge/src/arm/assembler-arm-inl.h
/branches/bleeding_edge/src/arm/builtins-arm.cc
/branches/bleeding_edge/src/arm/codegen-arm.cc
/branches/bleeding_edge/src/arm/deoptimizer-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
/branches/bleeding_edge/src/arm64/assembler-arm64-inl.h
/branches/bleeding_edge/src/arm64/builtins-arm64.cc
/branches/bleeding_edge/src/arm64/codegen-arm64.cc
/branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc
/branches/bleeding_edge/src/arm64/macro-assembler-arm64.h
/branches/bleeding_edge/src/assembler.cc
/branches/bleeding_edge/src/assembler.h
/branches/bleeding_edge/src/codegen.h
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/isolate.cc
/branches/bleeding_edge/src/isolate.h
/branches/bleeding_edge/src/objects-debug.cc
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/x64/codegen-x64.cc
/branches/bleeding_edge/test/cctest/cctest.status
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm-inl.h Fri Apr 25 11:00:37
2014 UTC
+++ /branches/bleeding_edge/src/arm/assembler-arm-inl.h Tue May 6 11:25:37
2014 UTC
@@ -222,7 +222,7 @@
}
-static const int kNoCodeAgeSequenceLength = 3;
+static const int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize;
Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
@@ -234,15 +234,15 @@
Code* RelocInfo::code_age_stub() {
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
return Code::GetCodeFromTargetAddress(
- Memory::Address_at(pc_ + Assembler::kInstrSize *
- (kNoCodeAgeSequenceLength - 1)));
+ Memory::Address_at(pc_ +
+ (kNoCodeAgeSequenceLength -
Assembler::kInstrSize)));
}
void RelocInfo::set_code_age_stub(Code* stub) {
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
- Memory::Address_at(pc_ + Assembler::kInstrSize *
- (kNoCodeAgeSequenceLength - 1)) =
+ Memory::Address_at(pc_ +
+ (kNoCodeAgeSequenceLength - Assembler::kInstrSize)) =
stub->instruction_start();
}
=======================================
--- /branches/bleeding_edge/src/arm/builtins-arm.cc Wed Apr 30 14:33:35
2014 UTC
+++ /branches/bleeding_edge/src/arm/builtins-arm.cc Tue May 6 11:25:37
2014 UTC
@@ -898,7 +898,7 @@
__ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
// Jump to point after the code-age stub.
- __ add(r0, r0, Operand(kNoCodeAgeSequenceLength *
Assembler::kInstrSize));
+ __ add(r0, r0, Operand(kNoCodeAgeSequenceLength));
__ mov(pc, r0);
}
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc Fri May 2 10:14:37 2014
UTC
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc Tue May 6 11:25:37 2014
UTC
@@ -822,47 +822,46 @@
static const uint32_t kCodeAgePatchFirstInstruction = 0xe24f0008;
#endif
-static byte* GetNoCodeAgeSequence(uint32_t* length) {
- // The sequence of instructions that is patched out for aging code is the
- // following boilerplate stack-building prologue that is found in
FUNCTIONS
- static bool initialized = false;
- static uint32_t sequence[kNoCodeAgeSequenceLength];
- byte* byte_sequence = reinterpret_cast<byte*>(sequence);
- *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize;
- if (!initialized) {
- // Since patcher is a large object, allocate it dynamically when
needed,
- // to avoid overloading the stack in stress conditions.
- SmartPointer<CodePatcher>
- patcher(new CodePatcher(byte_sequence, kNoCodeAgeSequenceLength));
- PredictableCodeSizeScope scope(patcher->masm(), *length);
- patcher->masm()->PushFixedFrame(r1);
- patcher->masm()->nop(ip.code());
- patcher->masm()->add(
- fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
- initialized = true;
- }
- return byte_sequence;
+CodeAgingHelper::CodeAgingHelper() {
+ ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength);
+ // Since patcher is a large object, allocate it dynamically when needed,
+ // to avoid overloading the stack in stress conditions.
+ // DONT_FLUSH is used because the CodeAgingHelper is initialized early in
+ // the process, before ARM simulator ICache is setup.
+ SmartPointer<CodePatcher> patcher(
+ new CodePatcher(young_sequence_.start(),
+ young_sequence_.length() / Assembler::kInstrSize,
+ CodePatcher::DONT_FLUSH));
+ PredictableCodeSizeScope scope(patcher->masm(),
young_sequence_.length());
+ patcher->masm()->PushFixedFrame(r1);
+ patcher->masm()->nop(ip.code());
+ patcher->masm()->add(
+ fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+}
+
+
+#ifdef DEBUG
+bool CodeAgingHelper::IsOld(byte* candidate) const {
+ return Memory::uint32_at(candidate) == kCodeAgePatchFirstInstruction;
}
+#endif
-bool Code::IsYoungSequence(byte* sequence) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
- bool result = !memcmp(sequence, young_sequence, young_length);
- ASSERT(result ||
- Memory::uint32_at(sequence) == kCodeAgePatchFirstInstruction);
+bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ bool result = isolate->code_aging_helper()->IsYoung(sequence);
+ ASSERT(result || isolate->code_aging_helper()->IsOld(sequence));
return result;
}
-void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
+void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity) {
- if (IsYoungSequence(sequence)) {
+ if (IsYoungSequence(isolate, sequence)) {
*age = kNoAgeCodeAge;
*parity = NO_MARKING_PARITY;
} else {
Address target_address = Memory::Address_at(
- sequence + Assembler::kInstrSize * (kNoCodeAgeSequenceLength - 1));
+ sequence + (kNoCodeAgeSequenceLength - Assembler::kInstrSize));
Code* stub = GetCodeFromTargetAddress(target_address);
GetCodeAgeAndParity(stub, age, parity);
}
@@ -873,10 +872,9 @@
byte* sequence,
Code::Age age,
MarkingParity parity) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
+ uint32_t young_length =
isolate->code_aging_helper()->young_sequence_length();
if (age == kNoAgeCodeAge) {
- CopyBytes(sequence, young_sequence, young_length);
+ isolate->code_aging_helper()->CopyYoungSequenceTo(sequence);
CPU::FlushICache(sequence, young_length);
} else {
Code* stub = GetCodeAgeStub(isolate, age, parity);
=======================================
--- /branches/bleeding_edge/src/arm/deoptimizer-arm.cc Wed Apr 30 09:50:58
2014 UTC
+++ /branches/bleeding_edge/src/arm/deoptimizer-arm.cc Tue May 6 11:25:37
2014 UTC
@@ -31,7 +31,7 @@
// Fail hard and early if we enter this code object again.
byte* pointer = code->FindCodeAgeSequence();
if (pointer != NULL) {
- pointer += kNoCodeAgeSequenceLength * Assembler::kInstrSize;
+ pointer += kNoCodeAgeSequenceLength;
} else {
pointer = code->instruction_start();
}
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue May 6
09:28:08 2014 UTC
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue May 6
11:25:37 2014 UTC
@@ -910,7 +910,7 @@
add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
} else {
PredictableCodeSizeScope predictible_code_size_scope(
- this, kNoCodeAgeSequenceLength * Assembler::kInstrSize);
+ this, kNoCodeAgeSequenceLength);
// The following three instructions must remain together and unmodified
// for code aging to work properly.
if (isolate()->IsCodePreAgingActive()) {
=======================================
--- /branches/bleeding_edge/src/arm64/assembler-arm64-inl.h Tue Apr 29
06:42:26 2014 UTC
+++ /branches/bleeding_edge/src/arm64/assembler-arm64-inl.h Tue May 6
11:25:37 2014 UTC
@@ -715,7 +715,7 @@
}
-static const int kCodeAgeSequenceSize = 5 * kInstructionSize;
+static const int kNoCodeAgeSequenceLength = 5 * kInstructionSize;
static const int kCodeAgeStubEntryOffset = 3 * kInstructionSize;
@@ -727,7 +727,6 @@
Code* RelocInfo::code_age_stub() {
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
- ASSERT(!Code::IsYoungSequence(pc_));
// Read the stub entry point from the code age sequence.
Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset;
return
Code::GetCodeFromTargetAddress(Memory::Address_at(stub_entry_address));
@@ -736,7 +735,7 @@
void RelocInfo::set_code_age_stub(Code* stub) {
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
- ASSERT(!Code::IsYoungSequence(pc_));
+ ASSERT(!Code::IsYoungSequence(stub->GetIsolate(), pc_));
// Overwrite the stub entry point in the code age sequence. This is
loaded as
// a literal so there is no need to call FlushICache here.
Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset;
=======================================
--- /branches/bleeding_edge/src/arm64/builtins-arm64.cc Wed Apr 30 14:33:35
2014 UTC
+++ /branches/bleeding_edge/src/arm64/builtins-arm64.cc Tue May 6 11:25:37
2014 UTC
@@ -887,7 +887,7 @@
}
// Jump to point after the code-age stub.
- __ Add(x0, x0, kCodeAgeSequenceSize);
+ __ Add(x0, x0, kNoCodeAgeSequenceLength);
__ Br(x0);
}
=======================================
--- /branches/bleeding_edge/src/arm64/codegen-arm64.cc Tue Apr 29 06:42:26
2014 UTC
+++ /branches/bleeding_edge/src/arm64/codegen-arm64.cc Tue May 6 11:25:37
2014 UTC
@@ -350,14 +350,41 @@
}
-bool Code::IsYoungSequence(byte* sequence) {
- return MacroAssembler::IsYoungSequence(sequence);
+CodeAgingHelper::CodeAgingHelper() {
+ ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength);
+ // The sequence of instructions that is patched out for aging code is the
+ // following boilerplate stack-building prologue that is found both in
+ // FUNCTION and OPTIMIZED_FUNCTION code:
+ PatchingAssembler patcher(young_sequence_.start(),
+ young_sequence_.length() / kInstructionSize);
+ // The young sequence is the frame setup code for FUNCTION code types.
It is
+ // generated by FullCodeGenerator::Generate.
+ MacroAssembler::EmitFrameSetupForCodeAgePatching(&patcher);
+
+#ifdef DEBUG
+ const int length = kCodeAgeStubEntryOffset / kInstructionSize;
+ ASSERT(old_sequence_.length() >= kCodeAgeStubEntryOffset);
+ PatchingAssembler patcher_old(old_sequence_.start(), length);
+ MacroAssembler::EmitCodeAgeSequence(&patcher_old, NULL);
+#endif
}
-void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
+#ifdef DEBUG
+bool CodeAgingHelper::IsOld(byte* candidate) const {
+ return memcmp(candidate, old_sequence_.start(), kCodeAgeStubEntryOffset)
== 0;
+}
+#endif
+
+
+bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ return MacroAssembler::IsYoungSequence(isolate, sequence);
+}
+
+
+void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity) {
- if (IsYoungSequence(sequence)) {
+ if (IsYoungSequence(isolate, sequence)) {
*age = kNoAgeCodeAge;
*parity = NO_MARKING_PARITY;
} else {
@@ -372,7 +399,8 @@
byte* sequence,
Code::Age age,
MarkingParity parity) {
- PatchingAssembler patcher(sequence, kCodeAgeSequenceSize /
kInstructionSize);
+ PatchingAssembler patcher(sequence,
+ kNoCodeAgeSequenceLength / kInstructionSize);
if (age == kNoAgeCodeAge) {
MacroAssembler::EmitFrameSetupForCodeAgePatching(&patcher);
} else {
=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc Tue May 6
09:28:08 2014 UTC
+++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc Tue May 6
11:25:37 2014 UTC
@@ -5067,7 +5067,8 @@
// TODO(jbramley): Other architectures use the internal memcpy to copy
the
// sequence. If this is a performance bottleneck, we should consider
caching
// the sequence and copying it in the same way.
- InstructionAccurateScope scope(this, kCodeAgeSequenceSize /
kInstructionSize);
+ InstructionAccurateScope scope(this,
+ kNoCodeAgeSequenceLength /
kInstructionSize);
ASSERT(jssp.Is(StackPointer()));
EmitFrameSetupForCodeAgePatching(this);
}
@@ -5075,7 +5076,8 @@
void MacroAssembler::EmitCodeAgeSequence(Code* stub) {
- InstructionAccurateScope scope(this, kCodeAgeSequenceSize /
kInstructionSize);
+ InstructionAccurateScope scope(this,
+ kNoCodeAgeSequenceLength /
kInstructionSize);
ASSERT(jssp.Is(StackPointer()));
EmitCodeAgeSequence(this, stub);
}
@@ -5099,7 +5101,7 @@
__ stp(fp, lr, MemOperand(jssp, 2 * kXRegSize));
__ add(fp, jssp, StandardFrameConstants::kFixedFrameSizeFromFp);
- __ AssertSizeOfCodeGeneratedSince(&start, kCodeAgeSequenceSize);
+ __ AssertSizeOfCodeGeneratedSince(&start, kNoCodeAgeSequenceLength);
}
@@ -5122,46 +5124,17 @@
__ AssertSizeOfCodeGeneratedSince(&start, kCodeAgeStubEntryOffset);
if (stub) {
__ dc64(reinterpret_cast<uint64_t>(stub->instruction_start()));
- __ AssertSizeOfCodeGeneratedSince(&start, kCodeAgeSequenceSize);
+ __ AssertSizeOfCodeGeneratedSince(&start, kNoCodeAgeSequenceLength);
}
}
-bool MacroAssembler::IsYoungSequence(byte* sequence) {
- // Generate a young sequence to compare with.
- const int length = kCodeAgeSequenceSize / kInstructionSize;
- static bool initialized = false;
- static byte young[kCodeAgeSequenceSize];
- if (!initialized) {
- PatchingAssembler patcher(young, length);
- // The young sequence is the frame setup code for FUNCTION code types.
It is
- // generated by FullCodeGenerator::Generate.
- MacroAssembler::EmitFrameSetupForCodeAgePatching(&patcher);
- initialized = true;
- }
-
- bool is_young = (memcmp(sequence, young, kCodeAgeSequenceSize) == 0);
- ASSERT(is_young || IsCodeAgeSequence(sequence));
+bool MacroAssembler::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ bool is_young = isolate->code_aging_helper()->IsYoung(sequence);
+ ASSERT(is_young ||
+ isolate->code_aging_helper()->IsOld(sequence));
return is_young;
}
-
-
-#ifdef DEBUG
-bool MacroAssembler::IsCodeAgeSequence(byte* sequence) {
- // The old sequence varies depending on the code age. However, the code
up
- // until kCodeAgeStubEntryOffset does not change, so we can check that
part to
- // get a reasonable level of verification.
- const int length = kCodeAgeStubEntryOffset / kInstructionSize;
- static bool initialized = false;
- static byte old[kCodeAgeStubEntryOffset];
- if (!initialized) {
- PatchingAssembler patcher(old, length);
- MacroAssembler::EmitCodeAgeSequence(&patcher, NULL);
- initialized = true;
- }
- return memcmp(sequence, old, kCodeAgeStubEntryOffset) == 0;
-}
-#endif
void MacroAssembler::TruncatingDiv(Register result,
=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64.h Tue May 6
08:05:27 2014 UTC
+++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64.h Tue May 6
11:25:37 2014 UTC
@@ -1987,13 +1987,7 @@
// Return true if the sequence is a young sequence geneated by
// EmitFrameSetupForCodeAgePatching. Otherwise, this method asserts that
the
// sequence is a code age sequence (emitted by EmitCodeAgeSequence).
- static bool IsYoungSequence(byte* sequence);
-
-#ifdef DEBUG
- // Return true if the sequence is a code age sequence generated by
- // EmitCodeAgeSequence.
- static bool IsCodeAgeSequence(byte* sequence);
-#endif
+ static bool IsYoungSequence(Isolate* isolate, byte* sequence);
// Jumps to found label if a prototype map has dictionary elements.
void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
=======================================
--- /branches/bleeding_edge/src/assembler.cc Wed Apr 30 09:50:58 2014 UTC
+++ /branches/bleeding_edge/src/assembler.cc Tue May 6 11:25:37 2014 UTC
@@ -724,7 +724,10 @@
last_id_ = 0;
last_position_ = 0;
byte* sequence = code->FindCodeAgeSequence();
- if (sequence != NULL && !Code::IsYoungSequence(sequence)) {
+ // We get the isolate from the map, because at serialization time
+ // the code pointer has been cloned and isn't really in heap space.
+ Isolate* isolate = code->map()->GetIsolate();
+ if (sequence != NULL && !Code::IsYoungSequence(isolate, sequence)) {
code_age_sequence_ = sequence;
} else {
code_age_sequence_ = NULL;
@@ -856,7 +859,7 @@
#ifdef VERIFY_HEAP
-void RelocInfo::Verify() {
+void RelocInfo::Verify(Isolate* isolate) {
switch (rmode_) {
case EMBEDDED_OBJECT:
Object::VerifyPointer(target_object());
@@ -873,7 +876,7 @@
CHECK(addr != NULL);
// Check that we can find the right code object.
Code* code = Code::GetCodeFromTargetAddress(addr);
- Object* found = code->GetIsolate()->FindCodeObject(addr);
+ Object* found = isolate->FindCodeObject(addr);
CHECK(found->IsCode());
CHECK(code->address() == HeapObject::cast(found)->address());
break;
@@ -895,7 +898,7 @@
UNREACHABLE();
break;
case CODE_AGE_SEQUENCE:
- ASSERT(Code::IsYoungSequence(pc_) || code_age_stub()->IsCode());
+ ASSERT(Code::IsYoungSequence(isolate, pc_) ||
code_age_stub()->IsCode());
break;
}
}
=======================================
--- /branches/bleeding_edge/src/assembler.h Wed Apr 30 12:25:18 2014 UTC
+++ /branches/bleeding_edge/src/assembler.h Tue May 6 11:25:37 2014 UTC
@@ -520,7 +520,7 @@
void Print(Isolate* isolate, FILE* out);
#endif // ENABLE_DISASSEMBLER
#ifdef VERIFY_HEAP
- void Verify();
+ void Verify(Isolate* isolate);
#endif
static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1;
=======================================
--- /branches/bleeding_edge/src/codegen.h Tue May 6 11:14:37 2014 UTC
+++ /branches/bleeding_edge/src/codegen.h Tue May 6 11:25:37 2014 UTC
@@ -130,6 +130,33 @@
static const int kNumberDictionaryProbes = 4;
+class CodeAgingHelper {
+ public:
+ CodeAgingHelper();
+
+ uint32_t young_sequence_length() const { return
young_sequence_.length(); }
+ bool IsYoung(byte* candidate) const {
+ return memcmp(candidate,
+ young_sequence_.start(),
+ young_sequence_.length()) == 0;
+ }
+ void CopyYoungSequenceTo(byte* new_buffer) const {
+ CopyBytes(new_buffer, young_sequence_.start(),
young_sequence_.length());
+ }
+
+#ifdef DEBUG
+ bool IsOld(byte* candidate) const;
+#endif
+
+ protected:
+ const EmbeddedVector<byte, kNoCodeAgeSequenceLength> young_sequence_;
+#ifdef DEBUG
+#ifdef V8_TARGET_ARCH_ARM64
+ const EmbeddedVector<byte, kNoCodeAgeSequenceLength> old_sequence_;
+#endif
+#endif
+};
+
} } // namespace v8::internal
#endif // V8_CODEGEN_H_
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Tue Apr 29 06:42:26
2014 UTC
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Tue May 6 11:25:37
2014 UTC
@@ -1050,37 +1050,33 @@
#undef __
-static byte* GetNoCodeAgeSequence(uint32_t* length) {
- static bool initialized = false;
- static byte sequence[kNoCodeAgeSequenceLength];
- *length = kNoCodeAgeSequenceLength;
- if (!initialized) {
- // The sequence of instructions that is patched out for aging code is
the
- // following boilerplate stack-building prologue that is found both in
- // FUNCTION and OPTIMIZED_FUNCTION code:
- CodePatcher patcher(sequence, kNoCodeAgeSequenceLength);
- patcher.masm()->push(ebp);
- patcher.masm()->mov(ebp, esp);
- patcher.masm()->push(esi);
- patcher.masm()->push(edi);
- initialized = true;
- }
- return sequence;
+CodeAgingHelper::CodeAgingHelper() {
+ ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength);
+ CodePatcher patcher(young_sequence_.start(), young_sequence_.length());
+ patcher.masm()->push(ebp);
+ patcher.masm()->mov(ebp, esp);
+ patcher.masm()->push(esi);
+ patcher.masm()->push(edi);
+}
+
+
+#ifdef DEBUG
+bool CodeAgingHelper::IsOld(byte* candidate) const {
+ return *candidate == kCallOpcode;
}
+#endif
-bool Code::IsYoungSequence(byte* sequence) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
- bool result = (!memcmp(sequence, young_sequence, young_length));
- ASSERT(result || *sequence == kCallOpcode);
+bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ bool result = isolate->code_aging_helper()->IsYoung(sequence);
+ ASSERT(result || isolate->code_aging_helper()->IsOld(sequence));
return result;
}
-void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
+void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity) {
- if (IsYoungSequence(sequence)) {
+ if (IsYoungSequence(isolate, sequence)) {
*age = kNoAgeCodeAge;
*parity = NO_MARKING_PARITY;
} else {
@@ -1097,10 +1093,9 @@
byte* sequence,
Code::Age age,
MarkingParity parity) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
+ uint32_t young_length =
isolate->code_aging_helper()->young_sequence_length();
if (age == kNoAgeCodeAge) {
- CopyBytes(sequence, young_sequence, young_length);
+ isolate->code_aging_helper()->CopyYoungSequenceTo(sequence);
CPU::FlushICache(sequence, young_length);
} else {
Code* stub = GetCodeAgeStub(isolate, age, parity);
=======================================
--- /branches/bleeding_edge/src/isolate.cc Mon May 5 07:10:38 2014 UTC
+++ /branches/bleeding_edge/src/isolate.cc Tue May 6 11:25:37 2014 UTC
@@ -133,8 +133,8 @@
per_thread = new PerIsolateThreadData(this, thread_id);
thread_data_table_->Insert(per_thread);
}
+ ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
}
- ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
return per_thread;
}
@@ -1425,6 +1425,7 @@
logger_(NULL),
stats_table_(NULL),
stub_cache_(NULL),
+ code_aging_helper_(NULL),
deoptimizer_data_(NULL),
materialized_object_store_(NULL),
capture_stack_trace_for_uncaught_exceptions_(false),
@@ -1660,6 +1661,8 @@
delete stub_cache_;
stub_cache_ = NULL;
+ delete code_aging_helper_;
+ code_aging_helper_ = NULL;
delete stats_table_;
stats_table_ = NULL;
@@ -1834,6 +1837,8 @@
#endif
#endif
+ code_aging_helper_ = new CodeAgingHelper();
+
{ // NOLINT
// Ensure that the thread has a valid stack guard. The v8::Locker
object
// will ensure this too, but we don't have to use lockers if we are
only
=======================================
--- /branches/bleeding_edge/src/isolate.h Mon May 5 07:10:38 2014 UTC
+++ /branches/bleeding_edge/src/isolate.h Tue May 6 11:25:37 2014 UTC
@@ -54,6 +54,7 @@
class InnerPointerToCodeCache;
class MaterializedObjectStore;
class NoAllocationStringAllocator;
+class CodeAgingHelper;
class RandomNumberGenerator;
class RegExpStack;
class SaveContext;
@@ -836,6 +837,7 @@
Heap* heap() { return &heap_; }
StatsTable* stats_table();
StubCache* stub_cache() { return stub_cache_; }
+ CodeAgingHelper* code_aging_helper() { return code_aging_helper_; }
DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
MaterializedObjectStore* materialized_object_store() {
@@ -1197,6 +1199,7 @@
StackGuard stack_guard_;
StatsTable* stats_table_;
StubCache* stub_cache_;
+ CodeAgingHelper* code_aging_helper_;
DeoptimizerData* deoptimizer_data_;
MaterializedObjectStore* materialized_object_store_;
ThreadLocalTop thread_local_top_;
=======================================
--- /branches/bleeding_edge/src/objects-debug.cc Fri May 2 10:27:12 2014
UTC
+++ /branches/bleeding_edge/src/objects-debug.cc Tue May 6 11:25:37 2014
UTC
@@ -627,8 +627,9 @@
kCodeAlignment));
relocation_info()->ObjectVerify();
Address last_gc_pc = NULL;
+ Isolate* isolate = GetIsolate();
for (RelocIterator it(this); !it.done(); it.next()) {
- it.rinfo()->Verify();
+ it.rinfo()->Verify(isolate);
// Ensure that GC will not iterate twice over the same pointer.
if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
CHECK(it.rinfo()->pc() != last_gc_pc);
=======================================
--- /branches/bleeding_edge/src/objects.cc Tue May 6 08:34:48 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Tue May 6 11:25:37 2014 UTC
@@ -11291,10 +11291,11 @@
if (sequence != NULL) {
Age age;
MarkingParity code_parity;
- GetCodeAgeAndParity(sequence, &age, &code_parity);
+ Isolate* isolate = GetIsolate();
+ GetCodeAgeAndParity(isolate, sequence, &age, &code_parity);
age = EffectiveAge(age);
if (age != kLastCodeAge && code_parity != current_parity) {
- PatchPlatformCodeAge(GetIsolate(),
+ PatchPlatformCodeAge(isolate,
sequence,
static_cast<Age>(age + 1),
current_parity);
@@ -11330,7 +11331,7 @@
}
Age age;
MarkingParity parity;
- GetCodeAgeAndParity(sequence, &age, &parity);
+ GetCodeAgeAndParity(GetIsolate(), sequence, &age, &parity);
return age;
}
=======================================
--- /branches/bleeding_edge/src/objects.h Tue May 6 08:05:27 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Tue May 6 11:25:37 2014 UTC
@@ -5625,7 +5625,7 @@
static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
void MakeOlder(MarkingParity);
- static bool IsYoungSequence(byte* sequence);
+ static bool IsYoungSequence(Isolate* isolate, byte* sequence);
bool IsOld();
Age GetAge();
// Gets the raw code age, including psuedo code-age values such as
@@ -5787,7 +5787,7 @@
byte* FindCodeAgeSequence();
static void GetCodeAgeAndParity(Code* code, Age* age,
MarkingParity* parity);
- static void GetCodeAgeAndParity(byte* sequence, Age* age,
+ static void GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age*
age,
MarkingParity* parity);
static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity
parity);
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc Wed Apr 30 08:38:20 2014
UTC
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc Tue May 6 11:25:37 2014
UTC
@@ -616,37 +616,36 @@
#undef __
-static byte* GetNoCodeAgeSequence(uint32_t* length) {
- static bool initialized = false;
- static byte sequence[kNoCodeAgeSequenceLength];
- *length = kNoCodeAgeSequenceLength;
- if (!initialized) {
- // The sequence of instructions that is patched out for aging code is
the
- // following boilerplate stack-building prologue that is found both in
- // FUNCTION and OPTIMIZED_FUNCTION code:
- CodePatcher patcher(sequence, kNoCodeAgeSequenceLength);
- patcher.masm()->pushq(rbp);
- patcher.masm()->movp(rbp, rsp);
- patcher.masm()->Push(rsi);
- patcher.masm()->Push(rdi);
- initialized = true;
- }
- return sequence;
+CodeAgingHelper::CodeAgingHelper() {
+ ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength);
+ // The sequence of instructions that is patched out for aging code is the
+ // following boilerplate stack-building prologue that is found both in
+ // FUNCTION and OPTIMIZED_FUNCTION code:
+ CodePatcher patcher(young_sequence_.start(), young_sequence_.length());
+ patcher.masm()->pushq(rbp);
+ patcher.masm()->movp(rbp, rsp);
+ patcher.masm()->Push(rsi);
+ patcher.masm()->Push(rdi);
+}
+
+
+#ifdef DEBUG
+bool CodeAgingHelper::IsOld(byte* candidate) const {
+ return *candidate == kCallOpcode;
}
+#endif
-bool Code::IsYoungSequence(byte* sequence) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
- bool result = (!memcmp(sequence, young_sequence, young_length));
- ASSERT(result || *sequence == kCallOpcode);
+bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
+ bool result = isolate->code_aging_helper()->IsYoung(sequence);
+ ASSERT(result || isolate->code_aging_helper()->IsOld(sequence));
return result;
}
-void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
+void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity) {
- if (IsYoungSequence(sequence)) {
+ if (IsYoungSequence(isolate, sequence)) {
*age = kNoAgeCodeAge;
*parity = NO_MARKING_PARITY;
} else {
@@ -663,10 +662,9 @@
byte* sequence,
Code::Age age,
MarkingParity parity) {
- uint32_t young_length;
- byte* young_sequence = GetNoCodeAgeSequence(&young_length);
+ uint32_t young_length =
isolate->code_aging_helper()->young_sequence_length();
if (age == kNoAgeCodeAge) {
- CopyBytes(sequence, young_sequence, young_length);
+ isolate->code_aging_helper()->CopyYoungSequenceTo(sequence);
CPU::FlushICache(sequence, young_length);
} else {
Code* stub = GetCodeAgeStub(isolate, age, parity);
=======================================
--- /branches/bleeding_edge/test/cctest/cctest.status Mon May 5 13:56:39
2014 UTC
+++ /branches/bleeding_edge/test/cctest/cctest.status Tue May 6 11:25:37
2014 UTC
@@ -30,9 +30,6 @@
# All tests prefixed with 'Bug' are expected to fail.
'test-api/Bug*': [FAIL],
- # BUG(3303). Crashes on mac builds, known race condition.
- 'test-lockers/MultithreadedParallelIsolates': [SKIP],
-
##############################################################################
# BUG(382): Weird test. Can't guarantee that it never times out.
'test-api/ApplyInterruption': [PASS, TIMEOUT],
--
--
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.