summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler.cc')
-rw-r--r--deps/v8/src/compiler.cc135
1 files changed, 88 insertions, 47 deletions
diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc
index 20aa558c3d..d55bf33bab 100644
--- a/deps/v8/src/compiler.cc
+++ b/deps/v8/src/compiler.cc
@@ -11,15 +11,16 @@
#include "src/codegen.h"
#include "src/compilation-cache.h"
#include "src/compiler/pipeline.h"
+#include "src/crankshaft/hydrogen.h"
+#include "src/crankshaft/lithium.h"
+#include "src/crankshaft/typing.h"
#include "src/debug/debug.h"
#include "src/debug/liveedit.h"
#include "src/deoptimizer.h"
#include "src/full-codegen/full-codegen.h"
#include "src/gdb-jit.h"
-#include "src/hydrogen.h"
#include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h"
-#include "src/lithium.h"
#include "src/log-inl.h"
#include "src/messages.h"
#include "src/parser.h"
@@ -31,7 +32,6 @@
#include "src/scopeinfo.h"
#include "src/scopes.h"
#include "src/snapshot/serialize.h"
-#include "src/typing.h"
#include "src/vm-state-inl.h"
namespace v8 {
@@ -172,9 +172,6 @@ CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub,
dependencies_(isolate, zone),
bailout_reason_(kNoReason),
prologue_offset_(Code::kPrologueOffsetNotSet),
- no_frame_ranges_(isolate->cpu_profiler()->is_profiling()
- ? new List<OffsetRange>(2)
- : nullptr),
track_positions_(FLAG_hydrogen_track_positions ||
isolate->cpu_profiler()->is_profiling()),
opt_count_(has_shared_info() ? shared_info()->opt_count() : 0),
@@ -200,7 +197,6 @@ CompilationInfo::CompilationInfo(ParseInfo* parse_info, CodeStub* code_stub,
CompilationInfo::~CompilationInfo() {
DisableFutureOptimization();
delete deferred_handles_;
- delete no_frame_ranges_;
#ifdef DEBUG
// Check that no dependent maps have been added or added dependent maps have
// been rolled back or committed.
@@ -249,13 +245,15 @@ bool CompilationInfo::ShouldSelfOptimize() {
void CompilationInfo::EnsureFeedbackVector() {
if (feedback_vector_.is_null()) {
- feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector(
- literal()->feedback_vector_spec());
+ Handle<TypeFeedbackMetadata> feedback_metadata =
+ TypeFeedbackMetadata::New(isolate(), literal()->feedback_vector_spec());
+ feedback_vector_ = TypeFeedbackVector::New(isolate(), feedback_metadata);
}
// It's very important that recompiles do not alter the structure of the
// type feedback vector.
- CHECK(!feedback_vector_->SpecDiffersFrom(literal()->feedback_vector_spec()));
+ CHECK(!feedback_vector_->metadata()->SpecDiffersFrom(
+ literal()->feedback_vector_spec()));
}
@@ -330,9 +328,8 @@ base::SmartArrayPointer<char> CompilationInfo::GetDebugName() const {
}
-bool CompilationInfo::MustReplaceUndefinedReceiverWithGlobalProxy() {
- return is_sloppy(language_mode()) && !is_native() &&
- scope()->has_this_declaration() && scope()->receiver()->is_used();
+bool CompilationInfo::ExpectsJSReceiverAsReceiver() {
+ return is_sloppy(language_mode()) && !is_native();
}
@@ -441,9 +438,10 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() {
if (info()->shared_info()->asm_function()) {
if (info()->osr_frame()) info()->MarkAsFrameSpecializing();
info()->MarkAsFunctionContextSpecializing();
- } else if (FLAG_turbo_type_feedback) {
- info()->MarkAsTypeFeedbackEnabled();
- info()->EnsureFeedbackVector();
+ } else if (info()->has_global_object() &&
+ FLAG_native_context_specialization) {
+ info()->MarkAsNativeContextSpecializing();
+ info()->MarkAsTypingEnabled();
}
if (!info()->shared_info()->asm_function() ||
FLAG_turbo_asm_deoptimization) {
@@ -705,15 +703,37 @@ static bool CompileUnoptimizedCode(CompilationInfo* info) {
}
+// TODO(rmcilroy): Remove this temporary work-around when ignition supports
+// catch and eval.
+static bool IgnitionShouldFallbackToFullCodeGen(Scope* scope) {
+ if (!FLAG_ignition_fallback_on_eval_and_catch) return false;
+
+ if (scope->is_eval_scope() || scope->is_catch_scope() ||
+ scope->calls_eval()) {
+ return true;
+ }
+ for (auto inner_scope : *scope->inner_scopes()) {
+ if (IgnitionShouldFallbackToFullCodeGen(inner_scope)) return true;
+ }
+ return false;
+}
+
+
static bool GenerateBytecode(CompilationInfo* info) {
DCHECK(AllowCompilation::IsAllowed(info->isolate()));
- if (!Compiler::Analyze(info->parse_info()) ||
- !interpreter::Interpreter::MakeBytecode(info)) {
+ bool success = false;
+ if (Compiler::Analyze(info->parse_info())) {
+ if (IgnitionShouldFallbackToFullCodeGen(info->scope())) {
+ success = FullCodeGenerator::MakeCode(info);
+ } else {
+ success = interpreter::Interpreter::MakeBytecode(info);
+ }
+ }
+ if (!success) {
Isolate* isolate = info->isolate();
if (!isolate->has_pending_exception()) isolate->StackOverflow();
- return false;
}
- return true;
+ return success;
}
@@ -730,7 +750,8 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
MaybeDisableOptimization(shared, lit->dont_optimize_reason());
- if (FLAG_ignition && info->closure()->PassesFilter(FLAG_ignition_filter)) {
+ if (FLAG_ignition && !shared->HasBuiltinFunctionId() &&
+ info->closure()->PassesFilter(FLAG_ignition_filter)) {
// Compile bytecode for the interpreter.
if (!GenerateBytecode(info)) return MaybeHandle<Code>();
} else {
@@ -750,6 +771,10 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
// Update the code and feedback vector for the shared function info.
shared->ReplaceCode(*info->code());
shared->set_feedback_vector(*info->feedback_vector());
+ if (info->has_bytecode_array()) {
+ DCHECK(shared->function_data()->IsUndefined());
+ shared->set_function_data(*info->bytecode_array());
+ }
return info->code();
}
@@ -776,7 +801,8 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
Handle<Code> code = info->code();
if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do.
- // Context specialization folds-in the context, so no sharing can occur.
+ // Function context specialization folds-in the function context,
+ // so no sharing can occur.
if (info->is_function_context_specializing()) return;
// Frame specialization implies function context specialization.
DCHECK(!info->is_frame_specializing());
@@ -786,19 +812,18 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
if (function->shared()->bound()) return;
// Cache optimized context-specific code.
- if (FLAG_cache_optimized_code) {
- Handle<SharedFunctionInfo> shared(function->shared());
- Handle<LiteralsArray> literals(function->literals());
- Handle<Context> native_context(function->context()->native_context());
- SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
- literals, info->osr_ast_id());
- }
+ Handle<SharedFunctionInfo> shared(function->shared());
+ Handle<LiteralsArray> literals(function->literals());
+ Handle<Context> native_context(function->context()->native_context());
+ SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code,
+ literals, info->osr_ast_id());
- // Do not cache context-independent code compiled for OSR.
+ // Do not cache (native) context-independent code compiled for OSR.
if (code->is_turbofanned() && info->is_osr()) return;
- // Cache optimized context-independent code.
- if (FLAG_turbo_cache_shared_code && code->is_turbofanned()) {
+ // Cache optimized (native) context-independent code.
+ if (FLAG_turbo_cache_shared_code && code->is_turbofanned() &&
+ !info->is_native_context_specializing()) {
DCHECK(!info->is_function_context_specializing());
DCHECK(info->osr_ast_id().IsNone());
Handle<SharedFunctionInfo> shared(function->shared());
@@ -841,9 +866,12 @@ bool Compiler::ParseAndAnalyze(ParseInfo* info) {
static bool GetOptimizedCodeNow(CompilationInfo* info) {
+ Isolate* isolate = info->isolate();
+ CanonicalHandleScope canonical(isolate);
+
if (!Compiler::ParseAndAnalyze(info->parse_info())) return false;
- TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
+ TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
OptimizedCompileJob job(info);
if (job.CreateGraph() != OptimizedCompileJob::SUCCEEDED ||
@@ -858,7 +886,7 @@ static bool GetOptimizedCodeNow(CompilationInfo* info) {
}
// Success!
- DCHECK(!info->isolate()->has_pending_exception());
+ DCHECK(!isolate->has_pending_exception());
InsertCodeIntoOptimizedCodeMap(info);
RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info,
info->shared_info());
@@ -868,6 +896,8 @@ static bool GetOptimizedCodeNow(CompilationInfo* info) {
static bool GetOptimizedCodeLater(CompilationInfo* info) {
Isolate* isolate = info->isolate();
+ CanonicalHandleScope canonical(isolate);
+
if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) {
if (FLAG_trace_concurrent_recompilation) {
PrintF(" ** Compilation queue full, will retry optimizing ");
@@ -1146,6 +1176,13 @@ void Compiler::CompileForLiveEdit(Handle<Script> script) {
}
+// Checks whether top level functions should be passed by {raw_filter}.
+static bool TopLevelFunctionPassesFilter(const char* raw_filter) {
+ Vector<const char> filter = CStrVector(raw_filter);
+ return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*');
+}
+
+
static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
Isolate* isolate = info->isolate();
PostponeInterruptsScope postpone(isolate);
@@ -1209,8 +1246,14 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
HistogramTimerScope timer(rate);
// Compile the code.
- if (!CompileUnoptimizedCode(info)) {
- return Handle<SharedFunctionInfo>::null();
+ if (FLAG_ignition && TopLevelFunctionPassesFilter(FLAG_ignition_filter)) {
+ if (!GenerateBytecode(info)) {
+ return Handle<SharedFunctionInfo>::null();
+ }
+ } else {
+ if (!CompileUnoptimizedCode(info)) {
+ return Handle<SharedFunctionInfo>::null();
+ }
}
// Allocate function.
@@ -1220,6 +1263,10 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
info->code(),
ScopeInfo::Create(info->isolate(), info->zone(), info->scope()),
info->feedback_vector());
+ if (info->has_bytecode_array()) {
+ DCHECK(result->function_data()->IsUndefined());
+ result->set_function_data(*info->bytecode_array());
+ }
DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position());
SharedFunctionInfo::InitFromFunctionLiteral(result, lit);
@@ -1230,9 +1277,10 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
result->set_allows_lazy_compilation_without_context(false);
}
- Handle<String> script_name = script->name()->IsString()
- ? Handle<String>(String::cast(script->name()))
- : isolate->factory()->empty_string();
+ Handle<String> script_name =
+ script->name()->IsString()
+ ? Handle<String>(String::cast(script->name()))
+ : isolate->factory()->empty_string();
Logger::LogEventsAndTags log_tag = info->is_eval()
? Logger::EVAL_TAG
: Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script);
@@ -1534,13 +1582,6 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
!LiveEditFunctionTracker::IsActive(isolate) &&
(!info.is_debug() || allow_lazy_without_ctx);
- if (outer_info->parse_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);
- }
-
bool lazy = FLAG_lazy && allow_lazy && !literal->should_eager_compile();
// Generate code
@@ -1763,7 +1804,7 @@ bool CompilationPhase::ShouldProduceTraceOutput() const {
#if DEBUG
void CompilationInfo::PrintAstForTesting() {
PrintF("--- Source from AST ---\n%s\n",
- PrettyPrinter(isolate(), zone()).PrintProgram(literal()));
+ PrettyPrinter(isolate()).PrintProgram(literal()));
}
#endif
} // namespace internal