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()) {
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());
}
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());
}
void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
+ void MarkAsInliningDisabled() { SetFlag(kInliningEnabled, false); }
+
bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); }
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) {
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
compiler_hints,
has_duplicate_parameters,
kHasDuplicateParameters)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, asm_function, kIsAsmFunction)
#if V8_HOST_ARCH_32_BIT
// 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();
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.
// 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);
kIsArrow,
kIsGenerator,
kIsConciseMethod,
+ kIsAsmFunction,
kCompilerHintsCount // Pseudo entry
};
// 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.
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;
}
// 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);
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;
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,
if (inner->force_eager_compilation_) {
force_eager_compilation_ = true;
}
+ if (asm_module_ && inner->scope_type() == FUNCTION_SCOPE) {
+ inner->asm_function_ = true;
+ }
}
}
// 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
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_; }
// 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.