Commit ddd72aa1 authored by danno@chromium.org's avatar danno@chromium.org

Only flush SharedFunctionInfo optimized code cache when necessary

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/14604007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14650 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1634369a
...@@ -53,14 +53,13 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList( ...@@ -53,14 +53,13 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
ASSERT(function->IsOptimized()); ASSERT(function->IsOptimized());
ASSERT(function->FunctionsInFunctionListShareSameCode()); ASSERT(function->FunctionsInFunctionListShareSameCode());
// The optimized code is going to be patched, so we cannot use it
// any more. Play safe and reset the whole cache.
function->shared()->ClearOptimizedCodeMap("deoptimized function");
// Get the optimized code. // Get the optimized code.
Code* code = function->code(); Code* code = function->code();
Address code_start_address = code->instruction_start(); Address code_start_address = code->instruction_start();
// The optimized code is going to be patched, so we cannot use it any more.
function->shared()->EvictFromOptimizedCodeMap(code, "deoptimized function");
// 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();
......
...@@ -123,14 +123,13 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList( ...@@ -123,14 +123,13 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
ASSERT(function->IsOptimized()); ASSERT(function->IsOptimized());
ASSERT(function->FunctionsInFunctionListShareSameCode()); ASSERT(function->FunctionsInFunctionListShareSameCode());
// The optimized code is going to be patched, so we cannot use it
// any more. Play safe and reset the whole cache.
function->shared()->ClearOptimizedCodeMap("deoptimized function");
// Get the optimized code. // Get the optimized code.
Code* code = function->code(); Code* code = function->code();
Address code_start_address = code->instruction_start(); Address code_start_address = code->instruction_start();
// The optimized code is going to be patched, so we cannot use it any more.
function->shared()->EvictFromOptimizedCodeMap(code, "deoptimized function");
// We will overwrite the code's relocation info in-place. Relocation info // We will overwrite the code's relocation info in-place. Relocation info
// is written backward. The relocation info is the payload of a byte // is written backward. The relocation info is the payload of a byte
// array. Later on we will slide this to the start of the byte array and // array. Later on we will slide this to the start of the byte array and
......
...@@ -9034,7 +9034,7 @@ void SharedFunctionInfo::InstallFromOptimizedCodeMap(JSFunction* function, ...@@ -9034,7 +9034,7 @@ void SharedFunctionInfo::InstallFromOptimizedCodeMap(JSFunction* function,
void SharedFunctionInfo::ClearOptimizedCodeMap(const char* reason) { void SharedFunctionInfo::ClearOptimizedCodeMap(const char* reason) {
if (!optimized_code_map()->IsSmi()) { if (!optimized_code_map()->IsSmi()) {
if (FLAG_trace_opt) { if (FLAG_trace_opt) {
PrintF("[clearing optimizing code map (%s) for ", reason); PrintF("[clearing entire optimizing code map (%s) for ", reason);
ShortPrint(); ShortPrint();
PrintF("]\n"); PrintF("]\n");
} }
...@@ -9043,6 +9043,41 @@ void SharedFunctionInfo::ClearOptimizedCodeMap(const char* reason) { ...@@ -9043,6 +9043,41 @@ void SharedFunctionInfo::ClearOptimizedCodeMap(const char* reason) {
} }
void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
const char* reason) {
if (optimized_code_map()->IsSmi()) return;
int i;
bool removed_entry = false;
FixedArray* code_map = FixedArray::cast(optimized_code_map());
for (i = 0; i < code_map->length(); i += kEntryLength) {
ASSERT(code_map->get(i)->IsNativeContext());
if (Code::cast(code_map->get(i + 1)) == optimized_code) {
if (FLAG_trace_opt) {
PrintF("[clearing optimizing code map (%s) for ", reason);
ShortPrint();
PrintF("]\n");
}
removed_entry = true;
break;
}
}
while (i < (code_map->length() - kEntryLength)) {
code_map->set(i, code_map->get(i + kEntryLength));
code_map->set(i + 1, code_map->get(i + 1 + kEntryLength));
code_map->set(i + 2, code_map->get(i + 2 + kEntryLength));
i += kEntryLength;
}
if (removed_entry) {
if (code_map->length() > kEntryLength) {
RightTrimFixedArray<FROM_MUTATOR>(GetHeap(), code_map, kEntryLength);
} else {
ClearOptimizedCodeMap(reason);
}
}
}
bool JSFunction::CompileLazy(Handle<JSFunction> function, bool JSFunction::CompileLazy(Handle<JSFunction> function,
ClearExceptionFlag flag) { ClearExceptionFlag flag) {
bool result = true; bool result = true;
......
...@@ -5822,6 +5822,9 @@ class SharedFunctionInfo: public HeapObject { ...@@ -5822,6 +5822,9 @@ class SharedFunctionInfo: public HeapObject {
// Clear optimized code map. // Clear optimized code map.
void ClearOptimizedCodeMap(const char* reason); void ClearOptimizedCodeMap(const char* reason);
// Removed a specific optimized code object from the optimized code map.
void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
// Add a new entry to the optimized code map. // Add a new entry to the optimized code map.
static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared, static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
Handle<Context> native_context, Handle<Context> native_context,
......
...@@ -7973,6 +7973,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { ...@@ -7973,6 +7973,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
JavaScriptFrame* frame = it.frame(); JavaScriptFrame* frame = it.frame();
RUNTIME_ASSERT(frame->function()->IsJSFunction()); RUNTIME_ASSERT(frame->function()->IsJSFunction());
Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate); Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
Handle<Code> optimized_code(function->code());
RUNTIME_ASSERT(type != Deoptimizer::EAGER || function->IsOptimized()); RUNTIME_ASSERT(type != Deoptimizer::EAGER || function->IsOptimized());
// Avoid doing too much work when running with --always-opt and keep // Avoid doing too much work when running with --always-opt and keep
...@@ -8010,8 +8011,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { ...@@ -8010,8 +8011,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
} else { } else {
Deoptimizer::DeoptimizeFunction(*function); Deoptimizer::DeoptimizeFunction(*function);
} }
// Flush optimized code cache for this function. // Evict optimized code for this function from the cache so that it doesn't
function->shared()->ClearOptimizedCodeMap("notify deoptimized"); // get used for new closures.
function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
"notify deoptimized");
return isolate->heap()->undefined_value(); return isolate->heap()->undefined_value();
} }
......
...@@ -55,13 +55,12 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList( ...@@ -55,13 +55,12 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
ASSERT(function->IsOptimized()); ASSERT(function->IsOptimized());
ASSERT(function->FunctionsInFunctionListShareSameCode()); ASSERT(function->FunctionsInFunctionListShareSameCode());
// The optimized code is going to be patched, so we cannot use it
// any more. Play safe and reset the whole cache.
function->shared()->ClearOptimizedCodeMap("deoptimized function");
// Get the optimized code. // Get the optimized code.
Code* code = function->code(); Code* code = function->code();
// The optimized code is going to be patched, so we cannot use it any more.
function->shared()->EvictFromOptimizedCodeMap(code, "deoptimized function");
// 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();
......
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