summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGCapabilities.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGCapabilities.h')
-rw-r--r--Source/JavaScriptCore/dfg/DFGCapabilities.h105
1 files changed, 44 insertions, 61 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.h b/Source/JavaScriptCore/dfg/DFGCapabilities.h
index a89c697f6..a9dc51325 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.h
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.h
@@ -39,41 +39,17 @@ namespace JSC { namespace DFG {
#if ENABLE(DFG_JIT)
// Fast check functions; if they return true it is still necessary to
// check opcodes.
-inline bool mightCompileEval(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
-}
-inline bool mightCompileProgram(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
-}
-inline bool mightCompileFunctionForCall(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
-}
-inline bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
-}
-
-inline bool mightInlineFunctionForCall(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount()
- && !codeBlock->ownerExecutable()->needsActivation();
-}
-inline bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount()
- && !codeBlock->ownerExecutable()->needsActivation();
-}
+bool mightCompileEval(CodeBlock*);
+bool mightCompileProgram(CodeBlock*);
+bool mightCompileFunctionForCall(CodeBlock*);
+bool mightCompileFunctionForConstruct(CodeBlock*);
+bool mightInlineFunctionForCall(CodeBlock*);
+bool mightInlineFunctionForClosureCall(CodeBlock*);
+bool mightInlineFunctionForConstruct(CodeBlock*);
// Opcode checking.
-inline bool canInlineResolveOperations(OpcodeID opcode, ResolveOperations* operations)
+inline bool canInlineResolveOperations(ResolveOperations* operations)
{
- // Don't try to inline a resolve for which we have no information
- if (operations->isEmpty())
- return false;
-
for (unsigned i = 0; i < operations->size(); i++) {
switch (operations->data()[i].m_operation) {
case ResolveOperation::ReturnGlobalObjectAsBase:
@@ -82,24 +58,20 @@ inline bool canInlineResolveOperations(OpcodeID opcode, ResolveOperations* opera
case ResolveOperation::GetAndReturnGlobalProperty:
case ResolveOperation::GetAndReturnGlobalVar:
case ResolveOperation::GetAndReturnGlobalVarWatchable:
+ case ResolveOperation::SkipScopes:
+ case ResolveOperation::SetBaseToScope:
+ case ResolveOperation::ReturnScopeAsBase:
+ case ResolveOperation::GetAndReturnScopedVar:
continue;
case ResolveOperation::Fail:
- // The DFG can handle generic cases of failed resolves
- ASSERT(opcode != op_resolve_base_to_global_dynamic);
- ASSERT(opcode != op_resolve_base_to_scope_with_top_scope_check);
- ASSERT(opcode != op_resolve_base_to_global);
- ASSERT(opcode != op_resolve_base_to_scope);
- if (opcode != op_resolve && opcode != op_resolve_base)
- return false;
+ // Fall-back resolves don't know how to deal with the ExecState* having a different
+ // global object (and scope) than the inlined code that is invoking that resolve.
+ return false;
case ResolveOperation::SkipTopScopeNode:
- case ResolveOperation::SkipScopes:
- case ResolveOperation::SetBaseToScope:
- case ResolveOperation::ReturnScopeAsBase:
- case ResolveOperation::GetAndReturnScopedVar:
- // These opcodes would be easy to support with inlining, but we currently don't do it.
- // The issue is that the scope chain will not be set correctly.
+ // We don't inline code blocks that create activations. Creation of
+ // activations is the only thing that leads to SkipTopScopeNode.
return false;
case ResolveOperation::CheckForDynamicEntriesBeforeGlobalScope:
@@ -123,10 +95,8 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_rshift:
case op_lshift:
case op_urshift:
- case op_pre_inc:
- case op_post_inc:
- case op_pre_dec:
- case op_post_dec:
+ case op_inc:
+ case op_dec:
case op_add:
case op_sub:
case op_negate:
@@ -171,11 +141,8 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_init_global_const:
case op_init_global_const_check:
case op_jmp:
- case op_loop:
case op_jtrue:
case op_jfalse:
- case op_loop_if_true:
- case op_loop_if_false:
case op_jeq_null:
case op_jneq_null:
case op_jless:
@@ -187,10 +154,6 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_jngreater:
case op_jngreatereq:
case op_loop_hint:
- case op_loop_if_less:
- case op_loop_if_lesseq:
- case op_loop_if_greater:
- case op_loop_if_greatereq:
case op_ret:
case op_end:
case op_call_put_result:
@@ -217,10 +180,12 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_jneq_ptr:
case op_put_to_base_variable:
case op_put_to_base:
+ case op_typeof:
+ case op_to_number:
return CanCompile;
case op_call_varargs:
- return ShouldProfile;
+ return MayInline;
case op_resolve:
case op_resolve_global_property:
@@ -230,6 +195,10 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_resolve_scoped_var_with_top_scope_check:
return CanCompile;
+ case op_get_scoped_var:
+ case op_put_scoped_var:
+ return CanCompile;
+
case op_resolve_base_to_global:
case op_resolve_base_to_global_dynamic:
case op_resolve_base_to_scope:
@@ -253,7 +222,7 @@ inline bool canInlineOpcode(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction
case op_resolve_scoped_var:
case op_resolve_scoped_var_on_top_scope:
case op_resolve_scoped_var_with_top_scope_check:
- return canInlineResolveOperations(opcodeID, codeBlock->resolveOperations(pc[3].u.operand));
+ return canInlineResolveOperations(pc[3].u.resolveOperations);
case op_resolve_base_to_global:
case op_resolve_base_to_global_dynamic:
@@ -262,8 +231,12 @@ inline bool canInlineOpcode(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction
case op_resolve_base:
case op_resolve_with_base:
case op_resolve_with_this:
- return canInlineResolveOperations(opcodeID, codeBlock->resolveOperations(pc[4].u.operand));
-
+ return canInlineResolveOperations(pc[4].u.resolveOperations);
+
+ case op_get_scoped_var:
+ case op_put_scoped_var:
+ return !codeBlock->needsFullScopeChain();
+
// Inlining doesn't correctly remap regular expression operands.
case op_new_regexp:
@@ -292,6 +265,7 @@ inline bool mightCompileProgram(CodeBlock*) { return false; }
inline bool mightCompileFunctionForCall(CodeBlock*) { return false; }
inline bool mightCompileFunctionForConstruct(CodeBlock*) { return false; }
inline bool mightInlineFunctionForCall(CodeBlock*) { return false; }
+inline bool mightInlineFunctionForClosureCall(CodeBlock*) { return false; }
inline bool mightInlineFunctionForConstruct(CodeBlock*) { return false; }
inline CapabilityLevel canCompileOpcode(OpcodeID, CodeBlock*, Instruction*) { return CannotCompile; }
@@ -337,6 +311,11 @@ inline bool canInlineFunctionForCall(CodeBlock* codeBlock)
return mightInlineFunctionForCall(codeBlock) && canInlineOpcodes(codeBlock);
}
+inline bool canInlineFunctionForClosureCall(CodeBlock* codeBlock)
+{
+ return mightInlineFunctionForClosureCall(codeBlock) && canInlineOpcodes(codeBlock);
+}
+
inline bool canInlineFunctionForConstruct(CodeBlock* codeBlock)
{
return mightInlineFunctionForConstruct(codeBlock) && canInlineOpcodes(codeBlock);
@@ -350,8 +329,12 @@ inline bool mightInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind
return mightInlineFunctionForConstruct(codeBlock);
}
-inline bool canInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
+inline bool canInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind, bool isClosureCall)
{
+ if (isClosureCall) {
+ ASSERT(kind == CodeForCall);
+ return canInlineFunctionForClosureCall(codeBlock);
+ }
if (kind == CodeForCall)
return canInlineFunctionForCall(codeBlock);
ASSERT(kind == CodeForConstruct);