summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler.cc
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2014-11-14 00:52:27 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2014-11-14 16:34:58 +0100
commit5d1b6d3e0fa4b97a490ef964be48aed9872e3ec1 (patch)
treeab5f510c4d83b175681de629395525bf7ec7cedb /deps/v8/src/compiler.cc
parent3b3d89bad26f5dfebe73fef6ae284ee78acbd5c9 (diff)
downloadandroid-node-v8-5d1b6d3e0fa4b97a490ef964be48aed9872e3ec1.tar.gz
android-node-v8-5d1b6d3e0fa4b97a490ef964be48aed9872e3ec1.tar.bz2
android-node-v8-5d1b6d3e0fa4b97a490ef964be48aed9872e3ec1.zip
deps: upgrade v8 to 3.30.37
Diffstat (limited to 'deps/v8/src/compiler.cc')
-rw-r--r--deps/v8/src/compiler.cc141
1 files changed, 91 insertions, 50 deletions
diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc
index d8467e54ee..ba5f3fd56e 100644
--- a/deps/v8/src/compiler.cc
+++ b/deps/v8/src/compiler.cc
@@ -6,6 +6,7 @@
#include "src/compiler.h"
+#include "src/ast-numbering.h"
#include "src/bootstrapper.h"
#include "src/codegen.h"
#include "src/compilation-cache.h"
@@ -52,7 +53,8 @@ CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone)
parameter_count_(0),
optimization_id_(-1),
ast_value_factory_(NULL),
- ast_value_factory_owned_(false) {
+ ast_value_factory_owned_(false),
+ aborted_due_to_dependency_change_(false) {
Initialize(script->GetIsolate(), BASE, zone);
}
@@ -65,7 +67,8 @@ CompilationInfo::CompilationInfo(Isolate* isolate, Zone* zone)
parameter_count_(0),
optimization_id_(-1),
ast_value_factory_(NULL),
- ast_value_factory_owned_(false) {
+ ast_value_factory_owned_(false),
+ aborted_due_to_dependency_change_(false) {
Initialize(isolate, STUB, zone);
}
@@ -80,7 +83,8 @@ CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info,
parameter_count_(0),
optimization_id_(-1),
ast_value_factory_(NULL),
- ast_value_factory_owned_(false) {
+ ast_value_factory_owned_(false),
+ aborted_due_to_dependency_change_(false) {
Initialize(script_->GetIsolate(), BASE, zone);
}
@@ -96,7 +100,8 @@ CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone)
parameter_count_(0),
optimization_id_(-1),
ast_value_factory_(NULL),
- ast_value_factory_owned_(false) {
+ ast_value_factory_owned_(false),
+ aborted_due_to_dependency_change_(false) {
Initialize(script_->GetIsolate(), BASE, zone);
}
@@ -109,7 +114,8 @@ CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, Isolate* isolate,
parameter_count_(0),
optimization_id_(-1),
ast_value_factory_(NULL),
- ast_value_factory_owned_(false) {
+ ast_value_factory_owned_(false),
+ aborted_due_to_dependency_change_(false) {
Initialize(isolate, STUB, zone);
code_stub_ = stub;
}
@@ -126,7 +132,8 @@ CompilationInfo::CompilationInfo(
parameter_count_(0),
optimization_id_(-1),
ast_value_factory_(NULL),
- ast_value_factory_owned_(false) {
+ ast_value_factory_owned_(false),
+ aborted_due_to_dependency_change_(false) {
Initialize(isolate, BASE, zone);
}
@@ -159,6 +166,14 @@ void CompilationInfo::Initialize(Isolate* isolate,
if (!script_.is_null() && script_->type()->value() == Script::TYPE_NATIVE) {
MarkAsNative();
}
+ // Compiling for the snapshot typically results in different code than
+ // compiling later on. This means that code recompiled with deoptimization
+ // support won't be "equivalent" (as defined by SharedFunctionInfo::
+ // EnableDeoptimizationSupport), so it will replace the old code and all
+ // its type feedback. To avoid this, always compile functions in the snapshot
+ // with deoptimization support.
+ if (isolate_->serializer_enabled()) EnableDeoptimizationSupport();
+
if (isolate_->debug()->is_active()) MarkAsDebug();
if (FLAG_context_specialization) MarkAsContextSpecializing();
if (FLAG_turbo_inlining) MarkAsInliningEnabled();
@@ -277,12 +292,13 @@ void CompilationInfo::PrepareForCompilation(Scope* scope) {
DCHECK(scope_ == NULL);
scope_ = scope;
- int length = function()->slot_count();
if (feedback_vector_.is_null()) {
// Allocate the feedback vector too.
- feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector(length);
+ feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector(
+ function()->slot_count(), function()->ic_slot_count());
}
- DCHECK(feedback_vector_->length() == length);
+ DCHECK(feedback_vector_->Slots() == function()->slot_count() &&
+ feedback_vector_->ICSlots() == function()->ic_slot_count());
}
@@ -398,9 +414,6 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() {
compiler::Pipeline pipeline(info());
pipeline.GenerateCode();
if (!info()->code().is_null()) {
- if (FLAG_turbo_deoptimization) {
- info()->context()->native_context()->AddOptimizedCode(*info()->code());
- }
return SetLastStatus(SUCCEEDED);
}
}
@@ -469,6 +482,9 @@ OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() {
DCHECK(last_status() == SUCCEEDED);
// TODO(turbofan): Currently everything is done in the first phase.
if (!info()->code().is_null()) {
+ if (FLAG_turbo_deoptimization) {
+ info()->context()->native_context()->AddOptimizedCode(*info()->code());
+ }
RecordOptimizationStats();
return last_status();
}
@@ -631,12 +647,7 @@ static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
static bool CompileUnoptimizedCode(CompilationInfo* info) {
DCHECK(AllowCompilation::IsAllowed(info->isolate()));
- DCHECK(info->function() != NULL);
- if (!Rewriter::Rewrite(info)) return false;
- if (!Scope::Analyze(info)) return false;
- DCHECK(info->scope() != NULL);
-
- if (!FullCodeGenerator::MakeCode(info)) {
+ if (!Compiler::Analyze(info) || !FullCodeGenerator::MakeCode(info)) {
Isolate* isolate = info->isolate();
if (!isolate->has_pending_exception()) isolate->StackOverflow();
return false;
@@ -657,7 +668,6 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
shared->set_strict_mode(lit->strict_mode());
SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
shared->set_bailout_reason(lit->dont_optimize_reason());
- shared->set_ast_node_count(lit->ast_node_count());
// Compile unoptimized code.
if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>();
@@ -727,17 +737,33 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
}
-static bool CompileOptimizedPrologue(CompilationInfo* info) {
- if (!Parser::Parse(info)) return false;
+static bool Renumber(CompilationInfo* info) {
+ if (!AstNumbering::Renumber(info->function(), info->zone())) return false;
+ if (!info->shared_info().is_null()) {
+ info->shared_info()->set_ast_node_count(info->function()->ast_node_count());
+ }
+ return true;
+}
+
+
+bool Compiler::Analyze(CompilationInfo* info) {
+ DCHECK(info->function() != NULL);
if (!Rewriter::Rewrite(info)) return false;
if (!Scope::Analyze(info)) return false;
+ if (!Renumber(info)) return false;
DCHECK(info->scope() != NULL);
return true;
}
+bool Compiler::ParseAndAnalyze(CompilationInfo* info) {
+ if (!Parser::Parse(info)) return false;
+ return Compiler::Analyze(info);
+}
+
+
static bool GetOptimizedCodeNow(CompilationInfo* info) {
- if (!CompileOptimizedPrologue(info)) return false;
+ if (!Compiler::ParseAndAnalyze(info)) return false;
TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
@@ -779,7 +805,7 @@ static bool GetOptimizedCodeLater(CompilationInfo* info) {
}
CompilationHandleScope handle_scope(info);
- if (!CompileOptimizedPrologue(info)) return false;
+ if (!Compiler::ParseAndAnalyze(info)) return false;
info->SaveHandles(); // Copy handles to the compilation handle scope.
TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
@@ -819,14 +845,17 @@ MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) {
MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) {
- DCHECK(!function->GetIsolate()->has_pending_exception());
+ Isolate* isolate = function->GetIsolate();
+ DCHECK(!isolate->has_pending_exception());
DCHECK(!function->is_compiled());
-
- if (FLAG_turbo_asm && function->shared()->asm_function()) {
+ // If the debugger is active, do not compile with turbofan unless we can
+ // deopt from turbofan code.
+ if (FLAG_turbo_asm && function->shared()->asm_function() &&
+ (FLAG_turbo_deoptimization || !isolate->debug()->is_active())) {
CompilationInfoWithZone info(function);
- VMState<COMPILER> state(info.isolate());
- PostponeInterruptsScope postpone(info.isolate());
+ VMState<COMPILER> state(isolate);
+ PostponeInterruptsScope postpone(isolate);
info.SetOptimizing(BailoutId::None(),
Handle<Code>(function->shared()->code()));
@@ -835,7 +864,10 @@ MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) {
info.MarkAsTypingEnabled();
info.MarkAsInliningDisabled();
- if (GetOptimizedCodeNow(&info)) return info.code();
+ if (GetOptimizedCodeNow(&info)) {
+ DCHECK(function->shared()->is_compiled());
+ return info.code();
+ }
}
if (function->shared()->is_compiled()) {
@@ -844,13 +876,12 @@ MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) {
CompilationInfoWithZone info(function);
Handle<Code> result;
- ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result,
- GetUnoptimizedCodeCommon(&info), Code);
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info),
+ Code);
- if (FLAG_always_opt &&
- info.isolate()->use_crankshaft() &&
+ if (FLAG_always_opt && isolate->use_crankshaft() &&
!info.shared_info()->optimization_disabled() &&
- !info.isolate()->DebuggerHasBreakPoints()) {
+ !isolate->DebuggerHasBreakPoints()) {
Handle<Code> opt_code;
if (Compiler::GetOptimizedCode(
function, result,
@@ -893,6 +924,8 @@ bool Compiler::EnsureCompiled(Handle<JSFunction> function,
// TODO(turbofan): In the future, unoptimized code with deopt support could
// be generated lazily once deopt is triggered.
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());
// Note that we use the same AST that we will use for generating the
@@ -1079,11 +1112,9 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
- Handle<String> source,
- Handle<Context> context,
- StrictMode strict_mode,
- ParseRestriction restriction,
- int scope_position) {
+ Handle<String> source, Handle<SharedFunctionInfo> outer_info,
+ Handle<Context> context, StrictMode strict_mode,
+ ParseRestriction restriction, int scope_position) {
Isolate* isolate = source->GetIsolate();
int source_length = source->length();
isolate->counters()->total_eval_size()->Increment(source_length);
@@ -1091,7 +1122,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
CompilationCache* compilation_cache = isolate->compilation_cache();
MaybeHandle<SharedFunctionInfo> maybe_shared_info =
- compilation_cache->LookupEval(source, context, strict_mode,
+ compilation_cache->LookupEval(source, outer_info, context, strict_mode,
scope_position);
Handle<SharedFunctionInfo> shared_info;
@@ -1118,8 +1149,8 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
// If caller is strict mode, the result must be in strict mode as well.
DCHECK(strict_mode == SLOPPY || shared_info->strict_mode() == STRICT);
if (!shared_info->dont_cache()) {
- compilation_cache->PutEval(
- source, context, shared_info, scope_position);
+ compilation_cache->PutEval(source, outer_info, context, shared_info,
+ scope_position);
}
}
} else if (shared_info->ic_age() != isolate->heap()->global_ic_age()) {
@@ -1163,7 +1194,12 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
compile_options == ScriptCompiler::kConsumeCodeCache &&
!isolate->debug()->is_loaded()) {
HistogramTimerScope timer(isolate->counters()->compile_deserialize());
- return CodeSerializer::Deserialize(isolate, *cached_data, source);
+ Handle<SharedFunctionInfo> result;
+ if (CodeSerializer::Deserialize(isolate, *cached_data, source)
+ .ToHandle(&result)) {
+ return result;
+ }
+ // Deserializer failed. Fall through to compile.
} else {
maybe_result = compilation_cache->LookupScript(
source, script_name, line_offset, column_offset,
@@ -1207,14 +1243,17 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
result = CompileToplevel(&info);
if (extension == NULL && !result.is_null() && !result->dont_cache()) {
compilation_cache->PutScript(source, context, result);
- if (FLAG_serialize_toplevel &&
+ // TODO(yangguo): Issue 3628
+ // With block scoping, top-level variables may resolve to a global,
+ // context, which makes the code context-dependent.
+ if (FLAG_serialize_toplevel && !FLAG_harmony_scoping &&
compile_options == ScriptCompiler::kProduceCodeCache) {
HistogramTimerScope histogram_timer(
isolate->counters()->compile_serialize());
*cached_data = CodeSerializer::Serialize(isolate, result, source);
if (FLAG_profile_deserialization) {
- PrintF("[Compiling and serializing %d bytes took %0.3f ms]\n",
- (*cached_data)->length(), timer.Elapsed().InMillisecondsF());
+ PrintF("[Compiling and serializing took %0.3f ms]\n",
+ timer.Elapsed().InMillisecondsF());
}
}
}
@@ -1269,7 +1308,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(
if (outer_info->is_toplevel() && outer_info->will_serialize()) {
// Make sure that if the toplevel code (possibly to be serialized),
- // the inner unction must be allowed to be compiled lazily.
+ // the inner function must be allowed to be compiled lazily.
DCHECK(allow_lazy);
}
@@ -1279,7 +1318,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(
Handle<Code> code = isolate->builtins()->CompileLazy();
info.SetCode(code);
scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate));
- } else if (FullCodeGenerator::MakeCode(&info)) {
+ } else if (Renumber(&info) && FullCodeGenerator::MakeCode(&info)) {
DCHECK(!info.code().is_null());
scope_info = ScopeInfo::Create(info.scope(), info.zone());
} else {
@@ -1403,8 +1442,10 @@ Handle<Code> Compiler::GetConcurrentlyOptimizedCode(OptimizedCompileJob* job) {
bool Compiler::DebuggerWantsEagerCompilation(CompilationInfo* info,
bool allow_lazy_without_ctx) {
- return LiveEditFunctionTracker::IsActive(info->isolate()) ||
- (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx);
+ if (LiveEditFunctionTracker::IsActive(info->isolate())) return true;
+ Debug* debug = info->isolate()->debug();
+ bool debugging = debug->is_active() || debug->has_break_points();
+ return debugging && !allow_lazy_without_ctx;
}