Commit 0733add0 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Deopt] Always patch deopted code to fail hard if entered.

Remove the --zap_code_space flag and always patch deopted code to hard fail
if called.

Also, as a drive-by add deopt code patching for Arm64.

BUG=v8:6246

Change-Id: Ibf1bc53692dbbe618132100a66c56a88c97fd62b
Reviewed-on: https://chromium-review.googlesource.com/496127Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45082}
parent 102606e8
...@@ -6220,9 +6220,8 @@ class V8_EXPORT HeapStatistics { ...@@ -6220,9 +6220,8 @@ class V8_EXPORT HeapStatistics {
size_t peak_malloced_memory() { return peak_malloced_memory_; } size_t peak_malloced_memory() { return peak_malloced_memory_; }
/** /**
* Returns a 0/1 boolean, which signifies whether the |--zap_code_space| * Returns a 0/1 boolean, which signifies whether the V8 overwrite heap
* option is enabled or not, which makes V8 overwrite heap garbage with a bit * garbage with a bit pattern.
* pattern.
*/ */
size_t does_zap_garbage() { return does_zap_garbage_; } size_t does_zap_garbage() { return does_zap_garbage_; }
......
...@@ -34,30 +34,28 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { ...@@ -34,30 +34,28 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
// code patching below, and is not needed any more. // code patching below, and is not needed any more.
code->InvalidateRelocation(); code->InvalidateRelocation();
if (FLAG_zap_code_space) { // Fail hard and early if we enter this code object again.
// Fail hard and early if we enter this code object again. byte* pointer = code->FindCodeAgeSequence();
byte* pointer = code->FindCodeAgeSequence(); if (pointer != NULL) {
if (pointer != NULL) { pointer += kNoCodeAgeSequenceLength;
pointer += kNoCodeAgeSequenceLength; } else {
} else { pointer = code->instruction_start();
pointer = code->instruction_start(); }
}
{ {
PatchingAssembler patcher(Assembler::IsolateData(isolate), pointer, 1); PatchingAssembler patcher(Assembler::IsolateData(isolate), pointer, 1);
patcher.bkpt(0); patcher.bkpt(0);
patcher.FlushICache(isolate); patcher.FlushICache(isolate);
} }
DeoptimizationInputData* data = DeoptimizationInputData* data =
DeoptimizationInputData::cast(code->deoptimization_data()); DeoptimizationInputData::cast(code->deoptimization_data());
int osr_offset = data->OsrPcOffset()->value(); int osr_offset = data->OsrPcOffset()->value();
if (osr_offset > 0) { if (osr_offset > 0) {
PatchingAssembler patcher(Assembler::IsolateData(isolate), PatchingAssembler patcher(Assembler::IsolateData(isolate),
code->instruction_start() + osr_offset, 1); code_start_address + osr_offset, 1);
patcher.bkpt(0); patcher.bkpt(0);
patcher.FlushICache(isolate); patcher.FlushICache(isolate);
}
} }
DeoptimizationInputData* deopt_data = DeoptimizationInputData* deopt_data =
......
...@@ -31,16 +31,35 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) { ...@@ -31,16 +31,35 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
Address code_start_address = code->instruction_start();
// Invalidate the relocation information, as it will become invalid by the // Invalidate the relocation information, as it will become invalid by the
// code patching below, and is not needed any more. // code patching below, and is not needed any more.
code->InvalidateRelocation(); code->InvalidateRelocation();
// TODO(jkummerow): if (FLAG_zap_code_space), make the code object's // Fail hard and early if we enter this code object again.
// entry sequence unusable (see other architectures). byte* pointer = code->FindCodeAgeSequence();
if (pointer != NULL) {
pointer += kNoCodeAgeSequenceLength;
} else {
pointer = code->instruction_start();
}
{
PatchingAssembler patcher(Assembler::IsolateData(isolate), pointer, 1);
patcher.brk(0);
}
DeoptimizationInputData* data =
DeoptimizationInputData::cast(code->deoptimization_data());
int osr_offset = data->OsrPcOffset()->value();
if (osr_offset > 0) {
PatchingAssembler patcher(Assembler::IsolateData(isolate),
code_start_address + osr_offset, 1);
patcher.brk(0);
}
DeoptimizationInputData* deopt_data = DeoptimizationInputData* deopt_data =
DeoptimizationInputData::cast(code->deoptimization_data()); DeoptimizationInputData::cast(code->deoptimization_data());
Address code_start_address = code->instruction_start();
#ifdef DEBUG #ifdef DEBUG
Address prev_call_address = NULL; Address prev_call_address = NULL;
#endif #endif
......
...@@ -716,8 +716,6 @@ DEFINE_BOOL(cleanup_code_caches_at_gc, true, ...@@ -716,8 +716,6 @@ DEFINE_BOOL(cleanup_code_caches_at_gc, true,
DEFINE_BOOL(use_marking_progress_bar, true, DEFINE_BOOL(use_marking_progress_bar, true,
"Use a progress bar to scan large objects in increments when " "Use a progress bar to scan large objects in increments when "
"incremental marking is active.") "incremental marking is active.")
DEFINE_BOOL(zap_code_space, DEBUG_BOOL,
"Zap free memory in code space with 0xCC while sweeping.")
DEFINE_BOOL(force_marking_deque_overflows, false, DEFINE_BOOL(force_marking_deque_overflows, false,
"force overflows of marking deque by reducing it's size " "force overflows of marking deque by reducing it's size "
"to 64 words") "to 64 words")
......
...@@ -94,25 +94,22 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) { ...@@ -94,25 +94,22 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
Address code_start_address = code->instruction_start(); Address code_start_address = code->instruction_start();
if (FLAG_zap_code_space) { // Fail hard and early if we enter this code object again.
// Fail hard and early if we enter this code object again. byte* pointer = code->FindCodeAgeSequence();
byte* pointer = code->FindCodeAgeSequence(); if (pointer != NULL) {
if (pointer != NULL) { pointer += kNoCodeAgeSequenceLength;
pointer += kNoCodeAgeSequenceLength; } else {
} else { pointer = code->instruction_start();
pointer = code->instruction_start(); }
} CodePatcher patcher(isolate, pointer, 1);
CodePatcher patcher(isolate, pointer, 1); patcher.masm()->int3();
patcher.masm()->int3();
DeoptimizationInputData* data =
DeoptimizationInputData* data = DeoptimizationInputData::cast(code->deoptimization_data());
DeoptimizationInputData::cast(code->deoptimization_data()); int osr_offset = data->OsrPcOffset()->value();
int osr_offset = data->OsrPcOffset()->value(); if (osr_offset > 0) {
if (osr_offset > 0) { CodePatcher osr_patcher(isolate, code_start_address + osr_offset, 1);
CodePatcher osr_patcher(isolate, code->instruction_start() + osr_offset, osr_patcher.masm()->int3();
1);
osr_patcher.masm()->int3();
}
} }
// We will overwrite the code's relocation info in-place. Relocation info // We will overwrite the code's relocation info in-place. Relocation info
......
...@@ -30,25 +30,22 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { ...@@ -30,25 +30,22 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
// code patching below, and is not needed any more. // code patching below, and is not needed any more.
code->InvalidateRelocation(); code->InvalidateRelocation();
if (FLAG_zap_code_space) { // Fail hard and early if we enter this code object again.
// Fail hard and early if we enter this code object again. byte* pointer = code->FindCodeAgeSequence();
byte* pointer = code->FindCodeAgeSequence(); if (pointer != NULL) {
if (pointer != NULL) { pointer += kNoCodeAgeSequenceLength;
pointer += kNoCodeAgeSequenceLength; } else {
} else { pointer = code->instruction_start();
pointer = code->instruction_start(); }
} CodePatcher patcher(isolate, pointer, 1);
CodePatcher patcher(isolate, pointer, 1); patcher.masm()->break_(0xCC);
patcher.masm()->break_(0xCC);
DeoptimizationInputData* data =
DeoptimizationInputData* data = DeoptimizationInputData::cast(code->deoptimization_data());
DeoptimizationInputData::cast(code->deoptimization_data()); int osr_offset = data->OsrPcOffset()->value();
int osr_offset = data->OsrPcOffset()->value(); if (osr_offset > 0) {
if (osr_offset > 0) { CodePatcher osr_patcher(isolate, code_start_address + osr_offset, 1);
CodePatcher osr_patcher(isolate, code->instruction_start() + osr_offset, osr_patcher.masm()->break_(0xCC);
1);
osr_patcher.masm()->break_(0xCC);
}
} }
DeoptimizationInputData* deopt_data = DeoptimizationInputData* deopt_data =
......
...@@ -30,25 +30,22 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { ...@@ -30,25 +30,22 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
// code patching below, and is not needed any more. // code patching below, and is not needed any more.
code->InvalidateRelocation(); code->InvalidateRelocation();
if (FLAG_zap_code_space) { // Fail hard and early if we enter this code object again.
// Fail hard and early if we enter this code object again. byte* pointer = code->FindCodeAgeSequence();
byte* pointer = code->FindCodeAgeSequence(); if (pointer != NULL) {
if (pointer != NULL) { pointer += kNoCodeAgeSequenceLength;
pointer += kNoCodeAgeSequenceLength; } else {
} else { pointer = code->instruction_start();
pointer = code->instruction_start(); }
} CodePatcher patcher(isolate, pointer, 1);
CodePatcher patcher(isolate, pointer, 1); patcher.masm()->break_(0xCC);
patcher.masm()->break_(0xCC);
DeoptimizationInputData* data =
DeoptimizationInputData* data = DeoptimizationInputData::cast(code->deoptimization_data());
DeoptimizationInputData::cast(code->deoptimization_data()); int osr_offset = data->OsrPcOffset()->value();
int osr_offset = data->OsrPcOffset()->value(); if (osr_offset > 0) {
if (osr_offset > 0) { CodePatcher osr_patcher(isolate, code_start_address + osr_offset, 1);
CodePatcher osr_patcher(isolate, code->instruction_start() + osr_offset, osr_patcher.masm()->break_(0xCC);
1);
osr_patcher.masm()->break_(0xCC);
}
} }
DeoptimizationInputData* deopt_data = DeoptimizationInputData* deopt_data =
......
...@@ -37,25 +37,22 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { ...@@ -37,25 +37,22 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
// code patching below, and is not needed any more. // code patching below, and is not needed any more.
code->InvalidateRelocation(); code->InvalidateRelocation();
if (FLAG_zap_code_space) { // Fail hard and early if we enter this code object again.
// Fail hard and early if we enter this code object again. byte* pointer = code->FindCodeAgeSequence();
byte* pointer = code->FindCodeAgeSequence(); if (pointer != NULL) {
if (pointer != NULL) { pointer += kNoCodeAgeSequenceLength;
pointer += kNoCodeAgeSequenceLength; } else {
} else { pointer = code->instruction_start();
pointer = code->instruction_start(); }
} CodePatcher patcher(isolate, pointer, 1);
CodePatcher patcher(isolate, pointer, 1); patcher.masm()->bkpt(0);
patcher.masm()->bkpt(0);
DeoptimizationInputData* data =
DeoptimizationInputData* data = DeoptimizationInputData::cast(code->deoptimization_data());
DeoptimizationInputData::cast(code->deoptimization_data()); int osr_offset = data->OsrPcOffset()->value();
int osr_offset = data->OsrPcOffset()->value(); if (osr_offset > 0) {
if (osr_offset > 0) { CodePatcher osr_patcher(isolate, code_start_address + osr_offset, 1);
CodePatcher osr_patcher(isolate, code->instruction_start() + osr_offset, osr_patcher.masm()->bkpt(0);
1);
osr_patcher.masm()->bkpt(0);
}
} }
DeoptimizationInputData* deopt_data = DeoptimizationInputData* deopt_data =
......
...@@ -35,25 +35,22 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { ...@@ -35,25 +35,22 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
// code patching below, and is not needed any more. // code patching below, and is not needed any more.
code->InvalidateRelocation(); code->InvalidateRelocation();
if (FLAG_zap_code_space) { // Fail hard and early if we enter this code object again.
// Fail hard and early if we enter this code object again. byte* pointer = code->FindCodeAgeSequence();
byte* pointer = code->FindCodeAgeSequence(); if (pointer != NULL) {
if (pointer != NULL) { pointer += kNoCodeAgeSequenceLength;
pointer += kNoCodeAgeSequenceLength; } else {
} else { pointer = code->instruction_start();
pointer = code->instruction_start(); }
} CodePatcher patcher(isolate, pointer, 2);
CodePatcher patcher(isolate, pointer, 2); patcher.masm()->bkpt(0);
patcher.masm()->bkpt(0);
DeoptimizationInputData* data =
DeoptimizationInputData* data = DeoptimizationInputData::cast(code->deoptimization_data());
DeoptimizationInputData::cast(code->deoptimization_data()); int osr_offset = data->OsrPcOffset()->value();
int osr_offset = data->OsrPcOffset()->value(); if (osr_offset > 0) {
if (osr_offset > 0) { CodePatcher osr_patcher(isolate, code_start_address + osr_offset, 2);
CodePatcher osr_patcher(isolate, code->instruction_start() + osr_offset, osr_patcher.masm()->bkpt(0);
2);
osr_patcher.masm()->bkpt(0);
}
} }
DeoptimizationInputData* deopt_data = DeoptimizationInputData* deopt_data =
......
...@@ -30,29 +30,27 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) { ...@@ -30,29 +30,27 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
Address instruction_start = code->instruction_start();
// Invalidate the relocation information, as it will become invalid by the // Invalidate the relocation information, as it will become invalid by the
// code patching below, and is not needed any more. // code patching below, and is not needed any more.
code->InvalidateRelocation(); code->InvalidateRelocation();
if (FLAG_zap_code_space) { // Fail hard and early if we enter this code object again.
// Fail hard and early if we enter this code object again. byte* pointer = code->FindCodeAgeSequence();
byte* pointer = code->FindCodeAgeSequence(); if (pointer != NULL) {
if (pointer != NULL) { pointer += kNoCodeAgeSequenceLength;
pointer += kNoCodeAgeSequenceLength; } else {
} else { pointer = code->instruction_start();
pointer = code->instruction_start(); }
} CodePatcher patcher(isolate, pointer, 1);
CodePatcher patcher(isolate, pointer, 1); patcher.masm()->int3();
patcher.masm()->int3();
DeoptimizationInputData* data =
DeoptimizationInputData* data = DeoptimizationInputData::cast(code->deoptimization_data());
DeoptimizationInputData::cast(code->deoptimization_data()); int osr_offset = data->OsrPcOffset()->value();
int osr_offset = data->OsrPcOffset()->value(); if (osr_offset > 0) {
if (osr_offset > 0) { CodePatcher osr_patcher(isolate, instruction_start + osr_offset, 1);
CodePatcher osr_patcher(isolate, code->instruction_start() + osr_offset, osr_patcher.masm()->int3();
1);
osr_patcher.masm()->int3();
}
} }
// For each LLazyBailout instruction insert a absolute call to the // For each LLazyBailout instruction insert a absolute call to the
...@@ -61,7 +59,6 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { ...@@ -61,7 +59,6 @@ void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
// before the safepoint table (space was allocated there when the Code // before the safepoint table (space was allocated there when the Code
// object was created, if necessary). // object was created, if necessary).
Address instruction_start = code->instruction_start();
#ifdef DEBUG #ifdef DEBUG
Address prev_call_address = NULL; Address prev_call_address = NULL;
#endif #endif
......
...@@ -94,25 +94,22 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) { ...@@ -94,25 +94,22 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
Address code_start_address = code->instruction_start(); Address code_start_address = code->instruction_start();
if (FLAG_zap_code_space) { // Fail hard and early if we enter this code object again.
// Fail hard and early if we enter this code object again. byte* pointer = code->FindCodeAgeSequence();
byte* pointer = code->FindCodeAgeSequence(); if (pointer != NULL) {
if (pointer != NULL) { pointer += kNoCodeAgeSequenceLength;
pointer += kNoCodeAgeSequenceLength; } else {
} else { pointer = code->instruction_start();
pointer = code->instruction_start(); }
} CodePatcher patcher(isolate, pointer, 1);
CodePatcher patcher(isolate, pointer, 1); patcher.masm()->int3();
patcher.masm()->int3();
DeoptimizationInputData* data =
DeoptimizationInputData* data = DeoptimizationInputData::cast(code->deoptimization_data());
DeoptimizationInputData::cast(code->deoptimization_data()); int osr_offset = data->OsrPcOffset()->value();
int osr_offset = data->OsrPcOffset()->value(); if (osr_offset > 0) {
if (osr_offset > 0) { CodePatcher osr_patcher(isolate, code_start_address + osr_offset, 1);
CodePatcher osr_patcher(isolate, code->instruction_start() + osr_offset, osr_patcher.masm()->int3();
1);
osr_patcher.masm()->int3();
}
} }
// We will overwrite the code's relocation info in-place. Relocation info // We will overwrite the code's relocation info in-place. Relocation info
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment