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.h89
1 files changed, 75 insertions, 14 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.h b/Source/JavaScriptCore/dfg/DFGCapabilities.h
index dc6f7aa1c..e80cc28ae 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.h
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.h
@@ -68,6 +68,48 @@ inline bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
}
// Opcode checking.
+inline bool canInlineResolveOperations(OpcodeID opcode, 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:
+ case ResolveOperation::SetBaseToGlobal:
+ case ResolveOperation::SetBaseToUndefined:
+ case ResolveOperation::GetAndReturnGlobalProperty:
+ case ResolveOperation::GetAndReturnGlobalVar:
+ case ResolveOperation::GetAndReturnGlobalVarWatchable:
+ 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;
+
+ 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.
+ return false;
+
+ case ResolveOperation::CheckForDynamicEntriesBeforeGlobalScope:
+ // This would be easy to support in all cases.
+ return false;
+ }
+ }
+ return true;
+}
+
inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instruction*)
{
switch (opcodeID) {
@@ -116,8 +158,6 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_get_by_val:
case op_put_by_val:
case op_method_check:
- case op_get_scoped_var:
- case op_put_scoped_var:
case op_get_by_id:
case op_get_by_id_out_of_line:
case op_get_array_length:
@@ -127,10 +167,6 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_put_by_id_transition_direct_out_of_line:
case op_put_by_id_transition_normal:
case op_put_by_id_transition_normal_out_of_line:
- case op_get_global_var:
- case op_get_global_var_watchable:
- case op_put_global_var:
- case op_put_global_var_check:
case op_init_global_const:
case op_init_global_const_check:
case op_jmp:
@@ -157,9 +193,6 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_ret:
case op_end:
case op_call_put_result:
- case op_resolve:
- case op_resolve_base:
- case op_resolve_global:
case op_new_object:
case op_new_array:
case op_new_array_with_size:
@@ -181,11 +214,30 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_get_argument_by_val:
case op_get_arguments_length:
case op_jneq_ptr:
+ case op_put_to_base_variable:
+ case op_put_to_base:
return CanCompile;
case op_call_varargs:
return ShouldProfile;
+ case op_resolve:
+ case op_resolve_global_property:
+ case op_resolve_global_var:
+ case op_resolve_scoped_var:
+ case op_resolve_scoped_var_on_top_scope:
+ case op_resolve_scoped_var_with_top_scope_check:
+ return CanCompile;
+
+ case op_resolve_base_to_global:
+ case op_resolve_base_to_global_dynamic:
+ case op_resolve_base_to_scope:
+ case op_resolve_base_to_scope_with_top_scope_check:
+ case op_resolve_base:
+ case op_resolve_with_base:
+ case op_resolve_with_this:
+ return CanCompile;
+
default:
return CannotCompile;
}
@@ -194,13 +246,22 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
inline bool canInlineOpcode(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction* pc)
{
switch (opcodeID) {
-
- // 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.
- case op_get_scoped_var:
- case op_put_scoped_var:
case op_resolve:
+ case op_resolve_global_property:
+ case op_resolve_global_var:
+ 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));
+
+ case op_resolve_base_to_global:
+ case op_resolve_base_to_global_dynamic:
+ case op_resolve_base_to_scope:
+ case op_resolve_base_to_scope_with_top_scope_check:
case op_resolve_base:
+ case op_resolve_with_base:
+ case op_resolve_with_this:
+ return canInlineResolveOperations(opcodeID, codeBlock->resolveOperations(pc[4].u.operand));
// Inlining doesn't correctly remap regular expression operands.
case op_new_regexp: