Reviewers: Jakob,
Description:
When optimizing deserialized code, make sure IC state is preserved.
[email protected]
Please review this at https://codereview.chromium.org/737373003/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+46, -16 lines):
M src/compiler.cc
M src/flag-definitions.h
M src/full-codegen.cc
M src/objects.h
M src/objects-inl.h
M src/serialize.cc
A + test/mjsunit/deserialize-optimize-inner.js
Index: src/compiler.cc
diff --git a/src/compiler.cc b/src/compiler.cc
index
3b612c1323dbf5874fb56cbe6959e699cb9112f0..33d88d75c0dac5429165543eae3188b199b8d7c5
100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -938,16 +938,23 @@ bool
Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) {
DCHECK(info->function() != NULL);
DCHECK(info->scope() != NULL);
if (!info->shared_info()->has_deoptimization_support()) {
- CompilationInfoWithZone unoptimized(info->shared_info());
+ Handle<SharedFunctionInfo> shared = info->shared_info();
+ CompilationInfoWithZone unoptimized(shared);
// Note that we use the same AST that we will use for generating the
// optimized code.
unoptimized.SetFunction(info->function());
unoptimized.PrepareForCompilation(info->scope());
unoptimized.SetContext(info->context());
unoptimized.EnableDeoptimizationSupport();
+ // If the current code has reloc info for serialization, also include
+ // reloc info for serialization for the new code, so that deopt support
+ // can be added without losing IC state.
+ if (shared->code()->kind() == Code::FUNCTION &&
+ shared->code()->has_reloc_info_for_serialization()) {
+ unoptimized.PrepareForSerializing();
+ }
if (!FullCodeGenerator::MakeCode(&unoptimized)) return false;
- Handle<SharedFunctionInfo> shared = info->shared_info();
shared->EnableDeoptimizationSupport(*unoptimized.code());
shared->set_feedback_vector(*unoptimized.feedback_vector());
@@ -1313,10 +1320,10 @@ Handle<SharedFunctionInfo>
Compiler::BuildFunctionInfo(
bool allow_lazy = literal->AllowsLazyCompilation() &&
!DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx);
-
if (outer_info->is_toplevel() && outer_info->will_serialize()) {
// Make sure that if the toplevel code (possibly to be serialized),
// the inner function must be allowed to be compiled lazily.
+ // This is necessary to serialize toplevel code without inner
functions.
DCHECK(allow_lazy);
}
Index: src/flag-definitions.h
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index
535dcd2d7baaff380ca6bd2832d39b84470f9e82..0d7363e8f52828e32617ba7f382325771226df7e
100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -477,6 +477,7 @@ DEFINE_BOOL(trace_stub_failures, false,
"trace deoptimization of generated code stubs")
DEFINE_BOOL(serialize_toplevel, true, "enable caching of toplevel scripts")
+DEFINE_BOOL(serialize_inner, false, "enable caching of inner functions")
DEFINE_BOOL(trace_code_serializer, false, "print code serializer trace")
// compiler.cc
Index: src/full-codegen.cc
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index
e32c59fc0746278c468de226c038445fc7aa2897..cb8f4aafcd9cd7274f032f14505f5dd028725252
100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -338,6 +338,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info)
{
cgen.PopulateDeoptimizationData(code);
cgen.PopulateTypeFeedbackInfo(code);
code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
+ code->set_has_reloc_info_for_serialization(info->will_serialize());
code->set_handler_table(*cgen.handler_table());
code->set_compiled_optimizable(info->IsOptimizable());
code->set_allow_osr_at_loop_nesting_level(0);
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
3dd6fed8a9ed0b17f187cbf3c94cb1cdf6711c20..108f9f62489ad62b492ce22a748826a81baee62f
100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -4858,6 +4858,21 @@ void Code::set_compiled_optimizable(bool value) {
}
+bool Code::has_reloc_info_for_serialization() {
+ DCHECK_EQ(FUNCTION, kind());
+ byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
+ return FullCodeFlagsHasRelocInfoForSerialization::decode(flags);
+}
+
+
+void Code::set_has_reloc_info_for_serialization(bool value) {
+ DCHECK_EQ(FUNCTION, kind());
+ byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
+ flags = FullCodeFlagsHasRelocInfoForSerialization::update(flags, value);
+ WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
+}
+
+
int Code::allow_osr_at_loop_nesting_level() {
DCHECK_EQ(FUNCTION, kind());
int fields = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
678dcb2ed5d48b6c233977513ff94bfe22a324b1..9569de97329d9316e684448e8478d32a4377cffa
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -5103,6 +5103,12 @@ class Code: public HeapObject {
inline bool is_compiled_optimizable();
inline void set_compiled_optimizable(bool value);
+ // [has_reloc_info_for_serialization]: For FUNCTION kind, tells if its
+ // reloc info includes runtime and external references to support
+ // serialization/deserialization.
+ inline bool has_reloc_info_for_serialization();
+ inline void set_has_reloc_info_for_serialization(bool value);
+
// [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
// how long the function has been marked for OSR and therefore which
// level of loop nesting we are willing to do on-stack replacement
@@ -5387,6 +5393,8 @@ class Code: public HeapObject {
public BitField<bool, 0, 1> {}; // NOLINT
class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1>
{};
class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {};
+ class FullCodeFlagsHasRelocInfoForSerialization
+ : public BitField<bool, 3, 1> {};
static const int kProfilerTicksOffset = kFullCodeFlags + 1;
Index: src/serialize.cc
diff --git a/src/serialize.cc b/src/serialize.cc
index
f492f5b6cc08c6ff91e15b77214bb3abd346d6af..e502c9559fce70b186d4a911936bf042239e8c71
100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -2042,10 +2042,11 @@ void CodeSerializer::SerializeObject(HeapObject*
obj, HowToCode how_to_code,
SerializeIC(code_object, how_to_code, where_to_point);
return;
case Code::FUNCTION:
- // Only serialize the code for the toplevel function. Replace code
- // of included function literals by the lazy compile builtin.
+ DCHECK(code_object->has_reloc_info_for_serialization());
+ // Only serialize the code for the toplevel function unless
specified
+ // by flag. Replace code of inner functions by the lazy compile
builtin.
// This is safe, as checked in Compiler::BuildFunctionInfo.
- if (code_object != main_code_) {
+ if (code_object != main_code_ && !FLAG_serialize_inner) {
SerializeBuiltin(Builtins::kCompileLazy, how_to_code,
where_to_point);
} else {
code_object->MakeYoung();
@@ -2062,6 +2063,8 @@ void CodeSerializer::SerializeObject(HeapObject* obj,
HowToCode how_to_code,
CHECK(!obj->IsJSGlobalProxy() && !obj->IsGlobalObject());
// There should be no hash table embedded. They would require rehashing.
CHECK(!obj->IsHashTable());
+ // We expect no instantiated function objects or contexts.
+ CHECK(!obj->IsJSFunction() && !obj->IsContext());
SerializeGeneric(obj, how_to_code, where_to_point);
}
Index: test/mjsunit/deserialize-optimize-inner.js
diff --git a/test/mjsunit/debug-compile-optimized.js
b/test/mjsunit/deserialize-optimize-inner.js
similarity index 54%
copy from test/mjsunit/debug-compile-optimized.js
copy to test/mjsunit/deserialize-optimize-inner.js
index
468605abaab079d4b19250b90fed7048bec205aa..72df32018af497936ca870ed8901e993f614dcbf
100644
--- a/test/mjsunit/debug-compile-optimized.js
+++ b/test/mjsunit/deserialize-optimize-inner.js
@@ -2,17 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --expose-debug-as debug --allow-natives-syntax --crankshaft
+// Flags: --allow-natives-syntax --cache=code --no-lazy --serialize-inner
-Debug = debug.Debug;
+function f(x, y) { return x + y; }
-Debug.setListener(function() {});
-
-function f() {}
-f();
-f();
+assertEquals(1, f(0, 1));
+assertEquals(5, f(2, 3));
%OptimizeFunctionOnNextCall(f);
-f();
+assertEquals(9, f(4, 5));
assertOptimized(f);
-
-Debug.setListener(null);
--
--
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.