Widen the intake valve for TurboFan.
authortitzer@chromium.org <titzer@chromium.org>
Fri, 19 Sep 2014 12:50:50 +0000 (12:50 +0000)
committertitzer@chromium.org <titzer@chromium.org>
Fri, 19 Sep 2014 12:50:50 +0000 (12:50 +0000)
R=danno@chromium.org, mstarzinger@chromium.org
BUG=

Review URL: https://codereview.chromium.org/582703002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24083 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/compiler.cc
src/compiler.h
src/compiler/pipeline.cc
src/flag-definitions.h
src/objects-inl.h
src/objects.h
src/parser.cc
src/runtime.cc
src/scopeinfo.cc
src/scopes.cc
src/scopes.h

index 8653d81..685009e 100644 (file)
@@ -396,16 +396,7 @@ OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() {
   DCHECK(info()->shared_info()->has_deoptimization_support());
 
   // Check the whitelist for TurboFan.
-  if (info()->closure()->PassesFilter(FLAG_turbo_filter) &&
-      // TODO(turbofan): Make try-catch work and remove this bailout.
-      info()->function()->dont_optimize_reason() != kTryCatchStatement &&
-      info()->function()->dont_optimize_reason() != kTryFinallyStatement &&
-      // TODO(turbofan): Make ES6 for-of work and remove this bailout.
-      info()->function()->dont_optimize_reason() != kForOfStatement &&
-      // TODO(turbofan): Make super work and remove this bailout.
-      info()->function()->dont_optimize_reason() != kSuperReference &&
-      // TODO(turbofan): Make OSR work and remove this bailout.
-      !info()->is_osr()) {
+  if (info()->closure()->PassesFilter(FLAG_turbo_filter)) {
     compiler::Pipeline pipeline(info());
     pipeline.GenerateCode();
     if (!info()->code().is_null()) {
@@ -625,6 +616,7 @@ static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
   function_info->set_bailout_reason(lit->dont_optimize_reason());
   function_info->set_dont_cache(lit->flags()->Contains(kDontCache));
   function_info->set_kind(lit->kind());
+  function_info->set_asm_function(lit->scope()->asm_function());
 }
 
 
@@ -731,6 +723,38 @@ MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) {
 MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) {
   DCHECK(!function->GetIsolate()->has_pending_exception());
   DCHECK(!function->is_compiled());
+
+  if (FLAG_turbo_asm && function->shared()->asm_function()) {
+    CompilationInfoWithZone info(function);
+
+    VMState<COMPILER> state(info.isolate());
+    PostponeInterruptsScope postpone(info.isolate());
+
+    if (FLAG_trace_opt) {
+      // TODO(titzer): record and report full stats here.
+      PrintF("[optimizing asm ");
+      function->ShortPrint();
+      PrintF("]\n");
+    }
+
+    if (!Parser::Parse(&info)) return MaybeHandle<Code>();
+    if (!Rewriter::Rewrite(&info)) return MaybeHandle<Code>();
+    if (!Scope::Analyze(&info)) return MaybeHandle<Code>();
+    if (FLAG_turbo_deoptimization && !EnsureDeoptimizationSupport(&info)) {
+      return MaybeHandle<Code>();
+    }
+
+    info.SetOptimizing(BailoutId::None(),
+                       Handle<Code>(function->shared()->code()));
+
+    info.MarkAsContextSpecializing();
+    info.MarkAsTypingEnabled();
+    info.MarkAsInliningDisabled();
+    compiler::Pipeline pipeline(&info);
+    pipeline.GenerateCode();
+    if (!info.code().is_null()) return info.code();
+  }
+
   if (function->shared()->is_compiled()) {
     return Handle<Code>(function->shared()->code());
   }
index a7e83c8..ea93f40 100644 (file)
@@ -197,6 +197,8 @@ class CompilationInfo {
 
   void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
 
+  void MarkAsInliningDisabled() { SetFlag(kInliningEnabled, false); }
+
   bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
 
   void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); }
index 72f2093..1bd87b3 100644 (file)
@@ -151,6 +151,17 @@ static void TraceSchedule(Schedule* schedule) {
 
 
 Handle<Code> Pipeline::GenerateCode() {
+  if (info()->function()->dont_optimize_reason() == kTryCatchStatement ||
+      info()->function()->dont_optimize_reason() == kTryFinallyStatement ||
+      // TODO(turbofan): Make ES6 for-of work and remove this bailout.
+      info()->function()->dont_optimize_reason() == kForOfStatement ||
+      // TODO(turbofan): Make super work and remove this bailout.
+      info()->function()->dont_optimize_reason() == kSuperReference ||
+      // TODO(turbofan): Make OSR work and remove this bailout.
+      info()->is_osr()) {
+    return Handle<Code>::null();
+  }
+
   if (FLAG_turbo_stats) isolate()->GetTStatistics()->Initialize(info_);
 
   if (FLAG_trace_turbo) {
index 0d4f395..49f0714 100644 (file)
@@ -333,6 +333,7 @@ DEFINE_STRING(turbo_filter, "~", "optimization filter for TurboFan compiler")
 DEFINE_BOOL(trace_turbo, false, "trace generated TurboFan IR")
 DEFINE_BOOL(trace_turbo_types, true, "trace generated TurboFan types")
 DEFINE_BOOL(trace_turbo_scheduler, false, "trace generated TurboFan scheduler")
+DEFINE_BOOL(turbo_asm, false, "enable TurboFan for asm.js code")
 DEFINE_BOOL(turbo_verify, false, "verify TurboFan graphs at each phase")
 DEFINE_BOOL(turbo_stats, false, "print TurboFan statistics")
 #if V8_TURBOFAN_BACKEND
index 8c8b40c..e46dd8e 100644 (file)
@@ -5447,6 +5447,7 @@ BOOL_ACCESSORS(SharedFunctionInfo,
                compiler_hints,
                has_duplicate_parameters,
                kHasDuplicateParameters)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, asm_function, kIsAsmFunction)
 
 
 #if V8_HOST_ARCH_32_BIT
index 90dbfa5..a2f9c80 100644 (file)
@@ -4471,6 +4471,12 @@ class ScopeInfo : public FixedArray {
   // Return if contexts are allocated for this scope.
   bool HasContext();
 
+  // Return if this is a function scope with "use asm".
+  bool IsAsmModule() { return AsmModuleField::decode(Flags()); }
+
+  // Return if this is a nested function within an asm module scope.
+  bool IsAsmFunction() { return AsmFunctionField::decode(Flags()); }
+
   // Return the function_name if present.
   String* FunctionName();
 
@@ -4625,6 +4631,8 @@ class ScopeInfo : public FixedArray {
   class StrictModeField:       public BitField<StrictMode,           4, 1> {};
   class FunctionVariableField: public BitField<FunctionVariableInfo, 5, 2> {};
   class FunctionVariableMode:  public BitField<VariableMode,         7, 3> {};
+  class AsmModuleField : public BitField<bool, 10, 1> {};
+  class AsmFunctionField : public BitField<bool, 11, 1> {};
 
   // BitFields representing the encoded information for context locals in the
   // ContextLocalInfoEntries part.
@@ -7127,6 +7135,9 @@ class SharedFunctionInfo: public HeapObject {
   // Indicates that this function is a concise method.
   DECL_BOOLEAN_ACCESSORS(is_concise_method)
 
+  // Indicates that this function is an asm function.
+  DECL_BOOLEAN_ACCESSORS(asm_function)
+
   inline FunctionKind kind();
   inline void set_kind(FunctionKind kind);
 
@@ -7327,6 +7338,7 @@ class SharedFunctionInfo: public HeapObject {
     kIsArrow,
     kIsGenerator,
     kIsConciseMethod,
+    kIsAsmFunction,
     kCompilerHintsCount  // Pseudo entry
   };
 
index 9d10d30..0d3dc92 100644 (file)
@@ -1120,6 +1120,7 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
           // Store the usage count; The actual use counter on the isolate is
           // incremented after parsing is done.
           ++use_counts_[v8::Isolate::kUseAsm];
+          scope_->SetAsmModule();
         }
       } else {
         // End of the directive prologue.
index 743086f..45dd9a4 100644 (file)
@@ -8492,13 +8492,9 @@ RUNTIME_FUNCTION(Runtime_CompileLazy) {
   Handle<Code> code;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
                                      Compiler::GetLazyCode(function));
+  DCHECK(code->kind() == Code::FUNCTION ||
+         code->kind() == Code::OPTIMIZED_FUNCTION);
   function->ReplaceCode(*code);
-
-  // All done. Return the compiled code.
-  DCHECK(function->is_compiled());
-  DCHECK(function->code()->kind() == Code::FUNCTION ||
-         (FLAG_always_opt &&
-          function->code()->kind() == Code::OPTIMIZED_FUNCTION));
   return *code;
 }
 
index 6aed725..75bf014 100644 (file)
@@ -54,10 +54,12 @@ Handle<ScopeInfo> ScopeInfo::Create(Scope* scope, Zone* zone) {
 
   // Encode the flags.
   int flags = ScopeTypeField::encode(scope->scope_type()) |
-      CallsEvalField::encode(scope->calls_eval()) |
-      StrictModeField::encode(scope->strict_mode()) |
-      FunctionVariableField::encode(function_name_info) |
-      FunctionVariableMode::encode(function_variable_mode);
+              CallsEvalField::encode(scope->calls_eval()) |
+              StrictModeField::encode(scope->strict_mode()) |
+              FunctionVariableField::encode(function_name_info) |
+              FunctionVariableMode::encode(function_variable_mode) |
+              AsmModuleField::encode(scope->asm_module()) |
+              AsmFunctionField::encode(scope->asm_function());
   scope_info->SetFlags(flags);
   scope_info->SetParameterCount(parameter_count);
   scope_info->SetStackLocalCount(stack_local_count);
index e1297b3..440c7f2 100644 (file)
@@ -160,6 +160,8 @@ void Scope::SetDefaults(ScopeType scope_type,
   scope_inside_with_ = false;
   scope_contains_with_ = false;
   scope_calls_eval_ = false;
+  asm_module_ = false;
+  asm_function_ = outer_scope != NULL && outer_scope->asm_module_;
   // Inherit the strict mode from the parent scope.
   strict_mode_ = outer_scope != NULL ? outer_scope->strict_mode_ : SLOPPY;
   outer_scope_calls_sloppy_eval_ = false;
@@ -222,6 +224,8 @@ Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope,
                                       Handle<ScopeInfo>(scope_info),
                                       global_scope->ast_value_factory_,
                                       zone);
+      if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true;
+      if (scope_info->IsAsmModule()) current_scope->asm_module_ = true;
     } else if (context->IsBlockContext()) {
       ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
       current_scope = new(zone) Scope(current_scope,
@@ -1165,6 +1169,9 @@ void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) {
     if (inner->force_eager_compilation_) {
       force_eager_compilation_ = true;
     }
+    if (asm_module_ && inner->scope_type() == FUNCTION_SCOPE) {
+      inner->asm_function_ = true;
+    }
   }
 }
 
index 2757bf2..06c6c99 100644 (file)
@@ -214,6 +214,9 @@ class Scope: public ZoneObject {
   // Set the strict mode flag (unless disabled by a global flag).
   void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
 
+  // Set the ASM module flag.
+  void SetAsmModule() { asm_module_ = true; }
+
   // Position in the source where this scope begins and ends.
   //
   // * For the scope of a with statement
@@ -281,6 +284,8 @@ class Scope: public ZoneObject {
   bool outer_scope_calls_sloppy_eval() const {
     return outer_scope_calls_sloppy_eval_;
   }
+  bool asm_module() const { return asm_module_; }
+  bool asm_function() const { return asm_function_; }
 
   // Is this scope inside a with statement.
   bool inside_with() const { return scope_inside_with_; }
@@ -463,6 +468,10 @@ class Scope: public ZoneObject {
   // This scope or a nested catch scope or with scope contain an 'eval' call. At
   // the 'eval' call site this scope is the declaration scope.
   bool scope_calls_eval_;
+  // This scope contains an "use asm" annotation.
+  bool asm_module_;
+  // This scope's outer context is an asm module.
+  bool asm_function_;
   // The strict mode of this scope.
   StrictMode strict_mode_;
   // Source positions.