Reviewers: Toon Verwaest,
Description:
Use optimized code map to cache OSR code.
[email protected]
Please review this at https://codereview.chromium.org/100613004/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+73, -22 lines):
M src/code-stubs-hydrogen.cc
M src/compiler.cc
M src/factory.cc
M src/hydrogen-instructions.h
M src/mark-compact.cc
M src/objects.h
M src/objects.cc
M src/runtime.cc
Index: src/code-stubs-hydrogen.cc
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index
e52ec65c4b7632ac81cb082bfcd5d727cce3a574..b04403ff80778ee0e70ddff4aa76e40efdc5467c
100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -1189,6 +1189,10 @@ void
CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
// optimized_map points to fixed array of 3-element entries
// (native context, optimized code, literals).
// Map must never be empty, so check the first elements.
+ // Matching code that we find may have been compiled for OSR as
opposed to
+ // regular optimized code. That is probably because we never had the
+ // chance to compile regular optimized code before OSR engaged. In
that
+ // case, it's probably a good idea to just reuse that OSR code right
now.
Label install_optimized;
HValue* first_context_slot = Add<HLoadNamedField>(optimized_map,
HObjectAccess::ForFirstContextSlot());
Index: src/compiler.cc
diff --git a/src/compiler.cc b/src/compiler.cc
index
83f9ab2daffb78830e80a50e4aefe2aa171af624..d4a48b4c745fab92d66736614e4b8a37f6976177
100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -964,14 +964,14 @@ static void
InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
Handle<Code> code = info->code();
if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do.
- // Cache non-OSR optimized code.
- if (FLAG_cache_optimized_code && !info->is_osr()) {
+ // Cache optimized code.
+ if (FLAG_cache_optimized_code) {
Handle<JSFunction> function = info->closure();
Handle<SharedFunctionInfo> shared(function->shared());
Handle<FixedArray> literals(function->literals());
Handle<Context> native_context(function->context()->native_context());
SharedFunctionInfo::AddToOptimizedCodeMap(
- shared, native_context, code, literals);
+ shared, native_context, code, literals, info->osr_ast_id());
}
}
@@ -979,21 +979,26 @@ static void
InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) {
if (!info->IsOptimizing()) return false; // Nothing to look up.
- // Lookup non-OSR optimized code.
- if (FLAG_cache_optimized_code && !info->is_osr()) {
+ // Lookup optimized code.
+ if (FLAG_cache_optimized_code) {
Handle<SharedFunctionInfo> shared = info->shared_info();
Handle<JSFunction> function = info->closure();
ASSERT(!function.is_null());
Handle<Context> native_context(function->context()->native_context());
- int index = shared->SearchOptimizedCodeMap(*native_context);
+ int index = shared->SearchOptimizedCodeMap(*native_context,
+ info->osr_ast_id());
if (index > 0) {
if (FLAG_trace_opt) {
PrintF("[found optimized code for ");
function->ShortPrint();
+ if (info->is_osr()) {
+ PrintF(" with osr ast id %d ", info->osr_ast_id().ToInt());
+ }
PrintF("]\n");
}
// Caching of optimized code enabled and optimized code found.
shared->InstallFromOptimizedCodeMap(*function, index);
+ info->SetCode(Handle<Code>(function->code()));
return true;
}
}
@@ -1102,7 +1107,7 @@ bool Compiler::RecompileConcurrent(Handle<JSFunction>
closure,
{
CompilationHandleScope handle_scope(*info);
- if (!compiling_for_osr && InstallCodeFromOptimizedCodeMap(*info)) {
+ if (InstallCodeFromOptimizedCodeMap(*info)) {
return true;
}
@@ -1178,7 +1183,8 @@ Handle<Code>
Compiler::InstallOptimizedCode(RecompileJob* job) {
ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty(isolate));
info->closure()->ReplaceCode(*code);
if (info->shared_info()->SearchOptimizedCodeMap(
- info->closure()->context()->native_context()) == -1) {
+ info->closure()->context()->native_context(),
+ info->osr_ast_id()) == -1) {
InsertCodeIntoOptimizedCodeMap(*info);
}
if (FLAG_trace_concurrent_recompilation) {
Index: src/factory.cc
diff --git a/src/factory.cc b/src/factory.cc
index
483e6a632a3e6f975a9f8bee259869d5e318251a..bf3ee0ef811e014634e12ec819a85d36097ff6cd
100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -732,7 +732,8 @@ Handle<JSFunction>
Factory::NewFunctionFromSharedFunctionInfo(
result->set_context(*context);
- int index =
function_info->SearchOptimizedCodeMap(context->native_context());
+ int index = function_info->SearchOptimizedCodeMap(
+ context->native_context(), BailoutId::None());
if (!function_info->bound() && index < 0) {
int number_of_literals = function_info->num_literals();
Handle<FixedArray> literals = NewFixedArray(number_of_literals,
pretenure);
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index
d4beb6e1de2180b9fb903116a2d66b4dc7f21428..5a3b91775d7b1318b37e81117da7c1b5bb0074cb
100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -6018,6 +6018,12 @@ class HObjectAccess V8_FINAL {
return HObjectAccess(kInobject, SharedFunctionInfo::kFirstContextSlot);
}
+ static HObjectAccess ForFirstOsrAstIdSlot() {
+ return HObjectAccess(kInobject,
+ SharedFunctionInfo::kFirstOsrAstIdSlot,
+ Representation::Smi());
+ }
+
static HObjectAccess ForOptimizedCodeMap() {
return HObjectAccess(kInobject,
SharedFunctionInfo::kOptimizedCodeMapOffset);
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index
0e6b9804e09fe6776b0b61d97362d1d3ecf223ab..bc14bb495a307acf75079b88bc93a535a3e8e2cd
100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -1068,7 +1068,8 @@ void CodeFlusher::ProcessOptimizedCodeMaps() {
static const int kContextOffset = 0;
static const int kCodeOffset = 1;
static const int kLiteralsOffset = 2;
- STATIC_ASSERT(kEntryLength == 3);
+ static const int kOsrAstIdOffset = 3;
+ STATIC_ASSERT(kEntryLength == 4);
SharedFunctionInfo* holder = optimized_code_map_holder_head_;
SharedFunctionInfo* next_holder;
@@ -1112,6 +1113,10 @@ void CodeFlusher::ProcessOptimizedCodeMaps() {
Marking::MarkBitFrom(HeapObject::cast(*literals_slot))));
isolate_->heap()->mark_compact_collector()->
RecordSlot(literals_slot, literals_slot, *literals_slot);
+
+ // Update and record the osr ast id slot in the optimized code map.
+ code_map->set(new_length++, code_map->get(i + kOsrAstIdOffset));
+ ASSERT(code_map->get(i + kOsrAstIdOffset)->IsSmi());
}
// Trim the optimized code map if entries have been removed.
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
f96fd83849cff3090814484757f26b352932bc87..d0ed208b4d89d7cbd75cd4bf2e51c4ba0c4f5853
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -9543,22 +9543,26 @@ void SharedFunctionInfo::AddToOptimizedCodeMap(
Handle<SharedFunctionInfo> shared,
Handle<Context> native_context,
Handle<Code> code,
- Handle<FixedArray> literals) {
+ Handle<FixedArray> literals,
+ BailoutId osr_ast_id) {
CALL_HEAP_FUNCTION_VOID(
shared->GetIsolate(),
- shared->AddToOptimizedCodeMap(*native_context, *code, *literals));
+ shared->AddToOptimizedCodeMap(
+ *native_context, *code, *literals, osr_ast_id));
}
MaybeObject* SharedFunctionInfo::AddToOptimizedCodeMap(Context*
native_context,
Code* code,
- FixedArray*
literals) {
+ FixedArray*
literals,
+ BailoutId
osr_ast_id) {
ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
ASSERT(native_context->IsNativeContext());
- STATIC_ASSERT(kEntryLength == 3);
+ STATIC_ASSERT(kEntryLength == 4);
Heap* heap = GetHeap();
FixedArray* new_code_map;
Object* value = optimized_code_map();
+ Smi* osr_smi = Smi::FromInt(osr_ast_id.ToInt());
if (value->IsSmi()) {
// No optimized code map.
ASSERT_EQ(0, Smi::cast(value)->value());
@@ -9568,10 +9572,11 @@ MaybeObject*
SharedFunctionInfo::AddToOptimizedCodeMap(Context* native_context,
new_code_map->set(kEntriesStart + 0, native_context);
new_code_map->set(kEntriesStart + 1, code);
new_code_map->set(kEntriesStart + 2, literals);
+ new_code_map->set(kEntriesStart + 3, osr_smi);
} else {
// Copy old map and append one new entry.
FixedArray* old_code_map = FixedArray::cast(value);
- ASSERT_EQ(-1, SearchOptimizedCodeMap(native_context));
+ ASSERT_EQ(-1, SearchOptimizedCodeMap(native_context, osr_ast_id));
int old_length = old_code_map->length();
int new_length = old_length + kEntryLength;
MaybeObject* maybe = old_code_map->CopySize(new_length);
@@ -9579,6 +9584,7 @@ MaybeObject*
SharedFunctionInfo::AddToOptimizedCodeMap(Context* native_context,
new_code_map->set(old_length + 0, native_context);
new_code_map->set(old_length + 1, code);
new_code_map->set(old_length + 2, literals);
+ new_code_map->set(old_length + 3, osr_smi);
// Zap the old map for the sake of the heap verifier.
if (Heap::ShouldZapGarbage()) {
Object** data = old_code_map->data_start();
@@ -9592,6 +9598,7 @@ MaybeObject*
SharedFunctionInfo::AddToOptimizedCodeMap(Context* native_context,
ASSERT(Code::cast(new_code_map->get(i + 1))->kind() ==
Code::OPTIMIZED_FUNCTION);
ASSERT(new_code_map->get(i + 2)->IsFixedArray());
+ ASSERT(new_code_map->get(i + 3)->IsSmi());
}
#endif
set_optimized_code_map(new_code_map);
@@ -9653,6 +9660,7 @@ void
SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
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));
+ code_map->set(i + 3, code_map->get(i + 3 + kEntryLength));
i += kEntryLength;
}
if (removed_entry) {
@@ -10258,15 +10266,18 @@ void
SharedFunctionInfo::CompleteInobjectSlackTracking() {
}
-int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context) {
+int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
+ BailoutId osr_ast_id) {
ASSERT(native_context->IsNativeContext());
if (!FLAG_cache_optimized_code) return -1;
Object* value = optimized_code_map();
+ Smi* osr_smi = Smi::FromInt(osr_ast_id.ToInt());
if (!value->IsSmi()) {
FixedArray* optimized_code_map = FixedArray::cast(value);
int length = optimized_code_map->length();
for (int i = kEntriesStart; i < length; i += kEntryLength) {
- if (optimized_code_map->get(i) == native_context) {
+ if (optimized_code_map->get(i) == native_context &&
+ optimized_code_map->get(i + 3) == osr_smi) {
return i + 1;
}
}
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
bbdefc14a5942122092dd2f82345b4b4d73a2bb6..5256fc556d696b994bdbfde9ea923bded280f649
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -6537,7 +6537,7 @@ class SharedFunctionInfo: public HeapObject {
// Returns index i of the entry with the specified context. At position
// i - 1 is the context, position i the code, and i + 1 the literals
array.
// Returns -1 when no matching entry is found.
- int SearchOptimizedCodeMap(Context* native_context);
+ int SearchOptimizedCodeMap(Context* native_context, BailoutId
osr_ast_id);
// Installs optimized code from the code map on the given closure. The
// index has to be consistent with a search result as defined above.
@@ -6555,18 +6555,22 @@ class SharedFunctionInfo: public HeapObject {
// Add a new entry to the optimized code map.
MUST_USE_RESULT MaybeObject* AddToOptimizedCodeMap(Context*
native_context,
Code* code,
- FixedArray* literals);
+ FixedArray* literals,
+ BailoutId osr_ast_id);
static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
Handle<Context> native_context,
Handle<Code> code,
- Handle<FixedArray> literals);
+ Handle<FixedArray> literals,
+ BailoutId osr_ast_id);
// Layout description of the optimized code map.
static const int kNextMapIndex = 0;
static const int kEntriesStart = 1;
- static const int kEntryLength = 3;
+ static const int kEntryLength = 4;
static const int kFirstContextSlot = FixedArray::kHeaderSize +
kPointerSize;
static const int kFirstCodeSlot = FixedArray::kHeaderSize + 2 *
kPointerSize;
+ static const int kFirstOsrAstIdSlot =
+ FixedArray::kHeaderSize + 4 * kPointerSize;
static const int kSecondEntryIndex = kEntryLength + kEntriesStart;
static const int kInitialLength = kEntriesStart + kEntryLength;
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index
7dc96f201970eec90466b79f20fa2823271fe737..13f16bc3b02d38addc90dba89834902cfa9ecace
100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -8705,8 +8705,22 @@ RUNTIME_FUNCTION(MaybeObject*,
Runtime_CompileForOnStackReplacement) {
// Prevent regular recompilation if we queue this for OSR.
// TODO(yangguo): remove this as soon as OSR becomes one-shot.
function->ReplaceCode(*unoptimized);
+ } else if (function->IsOptimized() &&
+ !isolate->optimizing_compiler_thread()->
+ IsQueuedForOSR(function, pc_offset)) {
+ // Function has already been optimized and no OSR job has been
queued.
+ // This means that we have found cached code.
+ result = Handle<Code>(function->code());
+ DeoptimizationInputData* data =
+ DeoptimizationInputData::cast(result->deoptimization_data());
+ ASSERT_LE(0, data->OsrPcOffset()->value());
+ ast_id = BailoutId(data->OsrAstId()->value());
+ ASSERT_EQ(ast_id.ToInt(),
+
unoptimized->TranslatePcOffsetToAstId(pc_offset).ToInt());
+ // Fall through to the part where we use the OSR code.
+ } else {
+ return NULL;
}
- return NULL;
}
// Fall through to the end in case of failure.
} else {
--
--
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/groups/opt_out.