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
This commit is contained in:
danno@chromium.org 2013-05-13 19:22:18 +00:00
parent 1634369af7
commit ddd72aa14f
6 changed files with 53 additions and 15 deletions

View File

@ -53,14 +53,13 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
ASSERT(function->IsOptimized());
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.
Code* code = function->code();
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
// code patching below, and is not needed any more.
code->InvalidateRelocation();

View File

@ -123,14 +123,13 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
ASSERT(function->IsOptimized());
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.
Code* code = function->code();
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
// 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

View File

@ -9034,7 +9034,7 @@ void SharedFunctionInfo::InstallFromOptimizedCodeMap(JSFunction* function,
void SharedFunctionInfo::ClearOptimizedCodeMap(const char* reason) {
if (!optimized_code_map()->IsSmi()) {
if (FLAG_trace_opt) {
PrintF("[clearing optimizing code map (%s) for ", reason);
PrintF("[clearing entire optimizing code map (%s) for ", reason);
ShortPrint();
PrintF("]\n");
}
@ -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,
ClearExceptionFlag flag) {
bool result = true;

View File

@ -5822,6 +5822,9 @@ class SharedFunctionInfo: public HeapObject {
// Clear optimized code map.
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.
static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
Handle<Context> native_context,

View File

@ -7973,6 +7973,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
JavaScriptFrame* frame = it.frame();
RUNTIME_ASSERT(frame->function()->IsJSFunction());
Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
Handle<Code> optimized_code(function->code());
RUNTIME_ASSERT(type != Deoptimizer::EAGER || function->IsOptimized());
// Avoid doing too much work when running with --always-opt and keep
@ -8010,8 +8011,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
} else {
Deoptimizer::DeoptimizeFunction(*function);
}
// Flush optimized code cache for this function.
function->shared()->ClearOptimizedCodeMap("notify deoptimized");
// Evict optimized code for this function from the cache so that it doesn't
// get used for new closures.
function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
"notify deoptimized");
return isolate->heap()->undefined_value();
}

View File

@ -55,13 +55,12 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
ASSERT(function->IsOptimized());
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.
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
// code patching below, and is not needed any more.
code->InvalidateRelocation();