Title: [153179] trunk/Source/_javascript_Core
Revision
153179
Author
oli...@apple.com
Date
2013-07-24 21:00:58 -0700 (Wed, 24 Jul 2013)

Log Message

fourthTier: rationalize DFG::CapabilityLevel and DFGCapabilities.[h|cpp]
https://bugs.webkit.org/show_bug.cgi?id=116696

Reviewed by Sam Weinig.

Make it so that all capability calculation is funneled through one function, which tells
you everything you wanted to know: can it be inlined, and can it be compiled.

This work will help with https://bugs.webkit.org/show_bug.cgi?id=116557, since now the
JIT has a fairly authoritative answer to the "can it be inlined" question.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::ProgramCodeBlock::capabilityLevelInternal):
(JSC::EvalCodeBlock::capabilityLevelInternal):
(JSC::FunctionCodeBlock::capabilityLevelInternal):
* bytecode/CodeBlock.h:
(CodeBlock):
(JSC::CodeBlock::capabilityLevel):
(JSC::CodeBlock::capabilityLevelState):
(ProgramCodeBlock):
(EvalCodeBlock):
(FunctionCodeBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::debugFail):
(DFG):
(JSC::DFG::canInlineResolveOperations):
(JSC::DFG::capabilityLevel):
* dfg/DFGCapabilities.h:
(DFG):
(JSC::DFG::capabilityLevel):
(JSC::DFG::evalCapabilityLevel):
(JSC::DFG::programCapabilityLevel):
(JSC::DFG::functionForCallCapabilityLevel):
(JSC::DFG::functionForConstructCapabilityLevel):
(JSC::DFG::canInlineFunctionForCall):
(JSC::DFG::canInlineFunctionForClosureCall):
(JSC::DFG::canInlineFunctionForConstruct):
* dfg/DFGCommon.h:
(JSC::DFG::canCompile):
(DFG):
(JSC::DFG::canInline):
(JSC::DFG::leastUpperBound):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::privateCompilePutByIdTransition):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::privateCompilePutByIdTransition):
* tools/CodeProfile.cpp:
(JSC::CodeProfile::sample):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (153178 => 153179)


--- trunk/Source/_javascript_Core/ChangeLog	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-07-25 04:00:58 UTC (rev 153179)
@@ -1,3 +1,59 @@
+2013-05-23  Filip Pizlo  <fpi...@apple.com>
+
+        fourthTier: rationalize DFG::CapabilityLevel and DFGCapabilities.[h|cpp]
+        https://bugs.webkit.org/show_bug.cgi?id=116696
+
+        Reviewed by Sam Weinig.
+        
+        Make it so that all capability calculation is funneled through one function, which tells
+        you everything you wanted to know: can it be inlined, and can it be compiled.
+        
+        This work will help with https://bugs.webkit.org/show_bug.cgi?id=116557, since now the
+        JIT has a fairly authoritative answer to the "can it be inlined" question.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::ProgramCodeBlock::capabilityLevelInternal):
+        (JSC::EvalCodeBlock::capabilityLevelInternal):
+        (JSC::FunctionCodeBlock::capabilityLevelInternal):
+        * bytecode/CodeBlock.h:
+        (CodeBlock):
+        (JSC::CodeBlock::capabilityLevel):
+        (JSC::CodeBlock::capabilityLevelState):
+        (ProgramCodeBlock):
+        (EvalCodeBlock):
+        (FunctionCodeBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::debugFail):
+        (DFG):
+        (JSC::DFG::canInlineResolveOperations):
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGCapabilities.h:
+        (DFG):
+        (JSC::DFG::capabilityLevel):
+        (JSC::DFG::evalCapabilityLevel):
+        (JSC::DFG::programCapabilityLevel):
+        (JSC::DFG::functionForCallCapabilityLevel):
+        (JSC::DFG::functionForConstructCapabilityLevel):
+        (JSC::DFG::canInlineFunctionForCall):
+        (JSC::DFG::canInlineFunctionForClosureCall):
+        (JSC::DFG::canInlineFunctionForConstruct):
+        * dfg/DFGCommon.h:
+        (JSC::DFG::canCompile):
+        (DFG):
+        (JSC::DFG::canInline):
+        (JSC::DFG::leastUpperBound):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compile):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::privateCompilePutByIdTransition):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::privateCompilePutByIdTransition):
+        * tools/CodeProfile.cpp:
+        (JSC::CodeProfile::sample):
+
 2013-05-22  Filip Pizlo  <fpi...@apple.com>
 
         Rename getJITCode and getJITType to jitCode and jitType.

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (153178 => 153179)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2013-07-25 04:00:58 UTC (rev 153179)
@@ -1592,7 +1592,7 @@
     , m_resolveOperations(other.m_resolveOperations)
     , m_putToBaseOperations(other.m_putToBaseOperations)
 #if ENABLE(JIT)
-    , m_canCompileWithDFGState(DFG::CapabilityLevelNotSet)
+    , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
 #endif
 {
     setNumParameters(other.numParameters());
@@ -2884,21 +2884,21 @@
     return static_cast<FunctionExecutable*>(ownerExecutable())->replaceWithDeferredOptimizedCodeFor(plan, m_isConstructor ? CodeForConstruct : CodeForCall);
 }
 
-DFG::CapabilityLevel ProgramCodeBlock::canCompileWithDFGInternal()
+DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal()
 {
-    return DFG::canCompileProgram(this);
+    return DFG::programCapabilityLevel(this);
 }
 
-DFG::CapabilityLevel EvalCodeBlock::canCompileWithDFGInternal()
+DFG::CapabilityLevel EvalCodeBlock::capabilityLevelInternal()
 {
-    return DFG::canCompileEval(this);
+    return DFG::evalCapabilityLevel(this);
 }
 
-DFG::CapabilityLevel FunctionCodeBlock::canCompileWithDFGInternal()
+DFG::CapabilityLevel FunctionCodeBlock::capabilityLevelInternal()
 {
     if (m_isConstructor)
-        return DFG::canCompileFunctionForConstruct(this);
-    return DFG::canCompileFunctionForCall(this);
+        return DFG::functionForConstructCapabilityLevel(this);
+    return DFG::functionForCallCapabilityLevel(this);
 }
 
 void CodeBlock::jettison()

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (153178 => 153179)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2013-07-25 04:00:58 UTC (rev 153179)
@@ -311,14 +311,14 @@
     }
     virtual CodeBlock* replacement() = 0;
 
-    virtual DFG::CapabilityLevel canCompileWithDFGInternal() = 0;
-    DFG::CapabilityLevel canCompileWithDFG()
+    virtual DFG::CapabilityLevel capabilityLevelInternal() = 0;
+    DFG::CapabilityLevel capabilityLevel()
     {
-        DFG::CapabilityLevel result = canCompileWithDFGInternal();
-        m_canCompileWithDFGState = result;
+        DFG::CapabilityLevel result = capabilityLevelInternal();
+        m_capabilityLevelState = result;
         return result;
     }
-    DFG::CapabilityLevel canCompileWithDFGState() { return m_canCompileWithDFGState; }
+    DFG::CapabilityLevel capabilityLevelState() { return m_capabilityLevelState; }
 
     bool hasOptimizedReplacement();
 #else
@@ -919,7 +919,7 @@
     // without holding any locks, because the GC is guaranteed to wait until any
     // concurrent compilation threads finish what they're doing.
     ConcurrentJITLock m_lock;
-
+    
 protected:
 #if ENABLE(JIT)
     virtual CompilationResult jitCompileImpl(ExecState*) = 0;
@@ -1120,7 +1120,7 @@
 #endif
     OwnPtr<RareData> m_rareData;
 #if ENABLE(JIT)
-    DFG::CapabilityLevel m_canCompileWithDFGState;
+    DFG::CapabilityLevel m_capabilityLevelState;
 #endif
 };
 
@@ -1159,7 +1159,7 @@
     virtual void jettisonImpl();
     virtual CompilationResult jitCompileImpl(ExecState*);
     virtual CodeBlock* replacement();
-    virtual DFG::CapabilityLevel canCompileWithDFGInternal();
+    virtual DFG::CapabilityLevel capabilityLevelInternal();
 #endif
 };
 
@@ -1185,7 +1185,7 @@
     virtual void jettisonImpl();
     virtual CompilationResult jitCompileImpl(ExecState*);
     virtual CodeBlock* replacement();
-    virtual DFG::CapabilityLevel canCompileWithDFGInternal();
+    virtual DFG::CapabilityLevel capabilityLevelInternal();
 #endif
     
 private:
@@ -1211,7 +1211,7 @@
     virtual void jettisonImpl();
     virtual CompilationResult jitCompileImpl(ExecState*);
     virtual CodeBlock* replacement();
-    virtual DFG::CapabilityLevel canCompileWithDFGInternal();
+    virtual DFG::CapabilityLevel capabilityLevelInternal();
 #endif
 };
 

Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp (153178 => 153179)


--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2013-07-25 04:00:58 UTC (rev 153179)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -66,52 +66,201 @@
         && !codeBlock->ownerExecutable()->needsActivation();
 }
 
-static inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, bool result)
+inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, CapabilityLevel result)
 {
-    ASSERT_UNUSED(result, !result);
-#if DFG_ENABLE(DEBUG_VERBOSE)
-    dataLogF("Cannot handle code block %p because of opcode %s.\n", codeBlock, opcodeNames[opcodeID]);
-#else
-    UNUSED_PARAM(codeBlock);
-    UNUSED_PARAM(opcodeID);
-    UNUSED_PARAM(result);
-#endif
+    if (Options::verboseCompilation() && !canCompile(result))
+        dataLog("Cannot compile code block ", *codeBlock, " because of opcode %s.\n", opcodeNames[opcodeID]);
 }
 
-static inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, CapabilityLevel result)
+// Opcode checking.
+inline bool canInlineResolveOperations(ResolveOperations* operations)
 {
-    ASSERT(result != CanCompile);
-#if DFG_ENABLE(DEBUG_VERBOSE)
-    if (result == CannotCompile)
-        dataLogF("Cannot handle code block %p because of opcode %s.\n", codeBlock, opcodeNames[opcodeID]);
-    else {
-        dataLogF("Cannot compile code block %p because of opcode %s, but inlining might be possible.\n", codeBlock, opcodeNames[opcodeID]);
+    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:
+        case ResolveOperation::SkipScopes:
+        case ResolveOperation::SetBaseToScope:
+        case ResolveOperation::ReturnScopeAsBase:
+        case ResolveOperation::GetAndReturnScopedVar:
+            continue;
+
+        case ResolveOperation::Fail:
+            // 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:
+            // 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:
+            // This would be easy to support in all cases.
+            return false;
+        }
     }
-#else
-    UNUSED_PARAM(codeBlock);
-    UNUSED_PARAM(opcodeID);
-    UNUSED_PARAM(result);
+    return true;
+}
+
+CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction* pc)
+{
+    switch (opcodeID) {
+    case op_enter:
+    case op_to_this:
+    case op_create_this:
+    case op_get_callee:
+    case op_bitand:
+    case op_bitor:
+    case op_bitxor:
+    case op_rshift:
+    case op_lshift:
+    case op_urshift:
+    case op_inc:
+    case op_dec:
+    case op_add:
+    case op_sub:
+    case op_negate:
+    case op_mul:
+    case op_mod:
+    case op_div:
+#if ENABLE(DEBUG_WITH_BREAKPOINT)
+    case op_debug:
 #endif
+    case op_mov:
+    case op_check_has_instance:
+    case op_instanceof:
+    case op_is_undefined:
+    case op_is_boolean:
+    case op_is_number:
+    case op_is_string:
+    case op_is_object:
+    case op_is_function:
+    case op_not:
+    case op_less:
+    case op_lesseq:
+    case op_greater:
+    case op_greatereq:
+    case op_eq:
+    case op_eq_null:
+    case op_stricteq:
+    case op_neq:
+    case op_neq_null:
+    case op_nstricteq:
+    case op_get_by_val:
+    case op_put_by_val:
+    case op_get_by_id:
+    case op_get_by_id_out_of_line:
+    case op_get_array_length:
+    case op_put_by_id:
+    case op_put_by_id_out_of_line:
+    case op_put_by_id_transition_direct:
+    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_init_global_const_nop:
+    case op_init_global_const:
+    case op_init_global_const_check:
+    case op_jmp:
+    case op_jtrue:
+    case op_jfalse:
+    case op_jeq_null:
+    case op_jneq_null:
+    case op_jless:
+    case op_jlesseq:
+    case op_jgreater:
+    case op_jgreatereq:
+    case op_jnless:
+    case op_jnlesseq:
+    case op_jngreater:
+    case op_jngreatereq:
+    case op_loop_hint:
+    case op_ret:
+    case op_end:
+    case op_call_put_result:
+    case op_new_object:
+    case op_new_array:
+    case op_new_array_with_size:
+    case op_new_array_buffer:
+    case op_strcat:
+    case op_to_primitive:
+    case op_throw:
+    case op_throw_static_error:
+    case op_call:
+    case op_construct:
+    case op_init_lazy_reg:
+    case op_create_arguments:
+    case op_tear_off_arguments:
+    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:
+    case op_typeof:
+    case op_to_number:
+        return CanCompileAndInline;
+        
+    case op_call_varargs:
+        if (codeBlock->usesArguments() && pc[3].u.operand == codeBlock->argumentsRegister())
+            return CanInline;
+        return CannotCompile;
+
+    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:
+        if (canInlineResolveOperations(pc[3].u.resolveOperations))
+            return CanCompileAndInline;
+        return CanCompile;
+
+    case op_get_scoped_var:
+    case op_put_scoped_var:
+        if (!codeBlock->needsFullScopeChain())
+            return CanCompileAndInline;
+        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:
+        if (canInlineResolveOperations(pc[4].u.resolveOperations))
+            return CanCompileAndInline;
+        return CanCompile;
+
+    case op_new_regexp: 
+    case op_create_activation:
+    case op_tear_off_activation:
+    case op_new_func:
+    case op_new_func_exp:
+        return CanCompile;
+
+    default:
+        return CannotCompile;
+    }
 }
 
-template<typename ReturnType, ReturnType (*canHandleOpcode)(OpcodeID, CodeBlock*, Instruction*)>
-ReturnType canHandleOpcodes(CodeBlock* codeBlock, ReturnType initialValue)
+CapabilityLevel capabilityLevel(CodeBlock* codeBlock)
 {
     Interpreter* interpreter = codeBlock->vm()->interpreter;
     Instruction* instructionsBegin = codeBlock->instructions().begin();
     unsigned instructionCount = codeBlock->instructions().size();
-    ReturnType result = initialValue;
+    CapabilityLevel result = CanCompileAndInline;
     
     for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount; ) {
         switch (interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode)) {
 #define DEFINE_OP(opcode, length) \
         case opcode: { \
-            ReturnType current = canHandleOpcode( \
-                opcode, codeBlock, instructionsBegin + bytecodeOffset); \
-            if (current < result) { \
-                result = current; \
-                debugFail(codeBlock, opcode, current); \
-            } \
+            result = leastUpperBound(result, capabilityLevel(opcode, codeBlock, instructionsBegin + bytecodeOffset)); \
+            debugFail(codeBlock, opcode, result); \
             bytecodeOffset += length; \
             break; \
         }
@@ -126,18 +275,6 @@
     return result;
 }
 
-CapabilityLevel canCompileOpcodes(CodeBlock* codeBlock)
-{
-    if (!MacroAssembler::supportsFloatingPoint())
-        return CannotCompile;
-    return canHandleOpcodes<CapabilityLevel, canCompileOpcode>(codeBlock, CanCompile);
-}
-
-bool canInlineOpcodes(CodeBlock* codeBlock)
-{
-    return canHandleOpcodes<bool, canInlineOpcode>(codeBlock, true);
-}
-
 #endif
 
 } } // namespace JSC::DFG

Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.h (153178 => 153179)


--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.h	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.h	2013-07-25 04:00:58 UTC (rev 153179)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -47,218 +47,9 @@
 bool mightInlineFunctionForClosureCall(CodeBlock*);
 bool mightInlineFunctionForConstruct(CodeBlock*);
 
-// Opcode checking.
-inline bool canInlineResolveOperations(ResolveOperations* operations)
-{
-    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:
-        case ResolveOperation::SkipScopes:
-        case ResolveOperation::SetBaseToScope:
-        case ResolveOperation::ReturnScopeAsBase:
-        case ResolveOperation::GetAndReturnScopedVar:
-            continue;
+inline CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction* pc);
 
-        case ResolveOperation::Fail:
-            // 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:
-            // 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:
-            // This would be easy to support in all cases.
-            return false;
-        }
-    }
-    return true;
-}
-
-inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instruction*)
-{
-    switch (opcodeID) {
-    case op_enter:
-    case op_to_this:
-    case op_create_this:
-    case op_get_callee:
-    case op_bitand:
-    case op_bitor:
-    case op_bitxor:
-    case op_rshift:
-    case op_lshift:
-    case op_urshift:
-    case op_inc:
-    case op_dec:
-    case op_add:
-    case op_sub:
-    case op_negate:
-    case op_mul:
-    case op_mod:
-    case op_div:
-#if ENABLE(DEBUG_WITH_BREAKPOINT)
-    case op_debug:
-#endif
-    case op_mov:
-    case op_check_has_instance:
-    case op_instanceof:
-    case op_is_undefined:
-    case op_is_boolean:
-    case op_is_number:
-    case op_is_string:
-    case op_is_object:
-    case op_is_function:
-    case op_not:
-    case op_less:
-    case op_lesseq:
-    case op_greater:
-    case op_greatereq:
-    case op_eq:
-    case op_eq_null:
-    case op_stricteq:
-    case op_neq:
-    case op_neq_null:
-    case op_nstricteq:
-    case op_get_by_val:
-    case op_put_by_val:
-    case op_get_by_id:
-    case op_get_by_id_out_of_line:
-    case op_get_array_length:
-    case op_put_by_id:
-    case op_put_by_id_out_of_line:
-    case op_put_by_id_transition_direct:
-    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_init_global_const_nop:
-    case op_init_global_const:
-    case op_init_global_const_check:
-    case op_jmp:
-    case op_jtrue:
-    case op_jfalse:
-    case op_jeq_null:
-    case op_jneq_null:
-    case op_jless:
-    case op_jlesseq:
-    case op_jgreater:
-    case op_jgreatereq:
-    case op_jnless:
-    case op_jnlesseq:
-    case op_jngreater:
-    case op_jngreatereq:
-    case op_loop_hint:
-    case op_ret:
-    case op_end:
-    case op_call_put_result:
-    case op_new_object:
-    case op_new_array:
-    case op_new_array_with_size:
-    case op_new_array_buffer:
-    case op_strcat:
-    case op_to_primitive:
-    case op_throw:
-    case op_throw_static_error:
-    case op_call:
-    case op_construct:
-    case op_new_regexp: 
-    case op_init_lazy_reg:
-    case op_create_activation:
-    case op_tear_off_activation:
-    case op_create_arguments:
-    case op_tear_off_arguments:
-    case op_new_func:
-    case op_new_func_exp:
-    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:
-    case op_typeof:
-    case op_to_number:
-        return CanCompile;
-        
-    case op_call_varargs:
-        return MayInline;
-
-    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_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:
-    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;
-    }
-}
-
-inline bool canInlineOpcode(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction* pc)
-{
-    switch (opcodeID) {
-    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(pc[3].u.resolveOperations);
-
-    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(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:
-        
-    // We don't support inlining code that creates activations or has nested functions.
-    case op_create_activation:
-    case op_tear_off_activation:
-    case op_new_func:
-    case op_new_func_exp:
-        return false;
-        
-    // Inlining supports op_call_varargs if it's a call that just forwards the caller's
-    // arguments.
-    case op_call_varargs:
-        return codeBlock->usesArguments() && pc[3].u.operand == codeBlock->argumentsRegister();
-        
-    default:
-        return canCompileOpcode(opcodeID, codeBlock, pc) == CanCompile;
-    }
-}
-
-CapabilityLevel canCompileOpcodes(CodeBlock*);
-bool canInlineOpcodes(CodeBlock*);
+CapabilityLevel capabilityLevel(CodeBlock*);
 #else // ENABLE(DFG_JIT)
 inline bool mightCompileEval(CodeBlock*) { return false; }
 inline bool mightCompileProgram(CodeBlock*) { return false; }
@@ -268,57 +59,55 @@
 inline bool mightInlineFunctionForClosureCall(CodeBlock*) { return false; }
 inline bool mightInlineFunctionForConstruct(CodeBlock*) { return false; }
 
-inline CapabilityLevel canCompileOpcode(OpcodeID, CodeBlock*, Instruction*) { return CannotCompile; }
-inline bool canInlineOpcode(OpcodeID, CodeBlock*, Instruction*) { return false; }
-inline CapabilityLevel canCompileOpcodes(CodeBlock*) { return CannotCompile; }
-inline bool canInlineOpcodes(CodeBlock*) { return false; }
+inline CapabilityLevel capabilityLevel(OpcodeID, CodeBlock*, Instruction*) { return CannotCompile; }
+inline CapabilityLevel capabilityLevel(CodeBlock*) { return CannotCompile; }
 #endif // ENABLE(DFG_JIT)
 
-inline CapabilityLevel canCompileEval(CodeBlock* codeBlock)
+inline CapabilityLevel evalCapabilityLevel(CodeBlock* codeBlock)
 {
     if (!mightCompileEval(codeBlock))
         return CannotCompile;
     
-    return canCompileOpcodes(codeBlock);
+    return capabilityLevel(codeBlock);
 }
 
-inline CapabilityLevel canCompileProgram(CodeBlock* codeBlock)
+inline CapabilityLevel programCapabilityLevel(CodeBlock* codeBlock)
 {
     if (!mightCompileProgram(codeBlock))
         return CannotCompile;
     
-    return canCompileOpcodes(codeBlock);
+    return capabilityLevel(codeBlock);
 }
 
-inline CapabilityLevel canCompileFunctionForCall(CodeBlock* codeBlock)
+inline CapabilityLevel functionForCallCapabilityLevel(CodeBlock* codeBlock)
 {
     if (!mightCompileFunctionForCall(codeBlock))
         return CannotCompile;
     
-    return canCompileOpcodes(codeBlock);
+    return capabilityLevel(codeBlock);
 }
 
-inline CapabilityLevel canCompileFunctionForConstruct(CodeBlock* codeBlock)
+inline CapabilityLevel functionForConstructCapabilityLevel(CodeBlock* codeBlock)
 {
     if (!mightCompileFunctionForConstruct(codeBlock))
         return CannotCompile;
     
-    return canCompileOpcodes(codeBlock);
+    return capabilityLevel(codeBlock);
 }
 
 inline bool canInlineFunctionForCall(CodeBlock* codeBlock)
 {
-    return mightInlineFunctionForCall(codeBlock) && canInlineOpcodes(codeBlock);
+    return mightInlineFunctionForCall(codeBlock) && canInline(capabilityLevel(codeBlock));
 }
 
 inline bool canInlineFunctionForClosureCall(CodeBlock* codeBlock)
 {
-    return mightInlineFunctionForClosureCall(codeBlock) && canInlineOpcodes(codeBlock);
+    return mightInlineFunctionForClosureCall(codeBlock) && canInline(capabilityLevel(codeBlock));
 }
 
 inline bool canInlineFunctionForConstruct(CodeBlock* codeBlock)
 {
-    return mightInlineFunctionForConstruct(codeBlock) && canInlineOpcodes(codeBlock);
+    return mightInlineFunctionForConstruct(codeBlock) && canInline(capabilityLevel(codeBlock));
 }
 
 inline bool mightInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)

Modified: trunk/Source/_javascript_Core/dfg/DFGCommon.h (153178 => 153179)


--- trunk/Source/_javascript_Core/dfg/DFGCommon.h	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/dfg/DFGCommon.h	2013-07-25 04:00:58 UTC (rev 153179)
@@ -261,8 +261,61 @@
 
 // Put things here that must be defined even if ENABLE(DFG_JIT) is false.
 
-enum CapabilityLevel { CannotCompile, MayInline, CanCompile, CapabilityLevelNotSet };
+enum CapabilityLevel { CannotCompile, CanInline, CanCompile, CanCompileAndInline, CapabilityLevelNotSet };
 
+inline bool canCompile(CapabilityLevel level)
+{
+    switch (level) {
+    case CanCompile:
+    case CanCompileAndInline:
+        return true;
+    default:
+        return false;
+    }
+}
+
+inline bool canInline(CapabilityLevel level)
+{
+    switch (level) {
+    case CanInline:
+    case CanCompileAndInline:
+        return true;
+    default:
+        return false;
+    }
+}
+
+inline CapabilityLevel leastUpperBound(CapabilityLevel a, CapabilityLevel b)
+{
+    switch (a) {
+    case CannotCompile:
+        return CannotCompile;
+    case CanInline:
+        switch (b) {
+        case CanInline:
+        case CanCompileAndInline:
+            return CanInline;
+        default:
+            return CannotCompile;
+        }
+    case CanCompile:
+        switch (b) {
+        case CanCompile:
+        case CanCompileAndInline:
+            return CanCompile;
+        default:
+            return CannotCompile;
+        }
+    case CanCompileAndInline:
+        return b;
+    case CapabilityLevelNotSet:
+        ASSERT_NOT_REACHED();
+        return CannotCompile;
+    }
+    ASSERT_NOT_REACHED();
+    return CannotCompile;
+}
+
 // Unconditionally disable DFG disassembly support if the DFG is not compiled in.
 inline bool shouldShowDisassembly()
 {

Modified: trunk/Source/_javascript_Core/dfg/DFGDriver.cpp (153178 => 153179)


--- trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2013-07-25 04:00:58 UTC (rev 153179)
@@ -64,7 +64,7 @@
     
     ASSERT(osrEntryBytecodeIndex != UINT_MAX);
 
-    if (!Options::useDFGJIT())
+    if (!Options::useDFGJIT() || !MacroAssembler::supportsFloatingPoint())
         return CompilationFailed;
 
     if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock->instructionCount()))

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (153178 => 153179)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2013-07-25 04:00:58 UTC (rev 153179)
@@ -565,18 +565,20 @@
 PassRefPtr<JITCode> JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffort effort)
 {
 #if ENABLE(VALUE_PROFILER)
-    DFG::CapabilityLevel level = m_codeBlock->canCompileWithDFG();
+    DFG::CapabilityLevel level = m_codeBlock->capabilityLevel();
     switch (level) {
     case DFG::CannotCompile:
         m_canBeOptimized = false;
+        m_canBeOptimizedOrInlined = false;
         m_shouldEmitProfiling = false;
         break;
-    case DFG::MayInline:
+    case DFG::CanInline:
         m_canBeOptimized = false;
         m_canBeOptimizedOrInlined = true;
         m_shouldEmitProfiling = true;
         break;
     case DFG::CanCompile:
+    case DFG::CanCompileAndInline:
         m_canBeOptimized = true;
         m_canBeOptimizedOrInlined = true;
         m_shouldEmitProfiling = true;

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (153178 => 153179)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2013-07-25 04:00:58 UTC (rev 153179)
@@ -705,7 +705,7 @@
     // If we succeed in all of our checks, and the code was optimizable, then make sure we
     // decrement the rare case counter.
 #if ENABLE(VALUE_PROFILER)
-    if (m_codeBlock->canCompileWithDFG() >= DFG::MayInline) {
+    if (m_codeBlock->capabilityLevelState() != DFG::CannotCompile) {
         sub32(
             TrustedImm32(1),
             AbsoluteAddress(&m_codeBlock->rareCaseProfileForBytecodeOffset(stubInfo->bytecodeIndex)->m_counter));

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp (153178 => 153179)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp	2013-07-25 04:00:58 UTC (rev 153179)
@@ -648,7 +648,7 @@
     // If we succeed in all of our checks, and the code was optimizable, then make sure we
     // decrement the rare case counter.
 #if ENABLE(VALUE_PROFILER)
-    if (m_codeBlock->canCompileWithDFG() >= DFG::MayInline) {
+    if (m_codeBlock->capabilityLevelState() != DFG::CannotCompile) {
         sub32(
             TrustedImm32(1),
             AbsoluteAddress(&m_codeBlock->rareCaseProfileForBytecodeOffset(stubInfo->bytecodeIndex)->m_counter));

Modified: trunk/Source/_javascript_Core/tools/CodeProfile.cpp (153178 => 153179)


--- trunk/Source/_javascript_Core/tools/CodeProfile.cpp	2013-07-25 04:00:56 UTC (rev 153178)
+++ trunk/Source/_javascript_Core/tools/CodeProfile.cpp	2013-07-25 04:00:58 UTC (rev 153179)
@@ -107,7 +107,7 @@
             CodeBlock* codeBlock = static_cast<CodeBlock*>(ownerUID);
             if (codeBlock->jitType() == JITCode::DFGJIT)
                 type = DFGJIT;
-            else if (codeBlock->canCompileWithDFGState() != DFG::CanCompile)
+            else if (!canCompile(codeBlock->capabilityLevelState()))
                 type = BaselineOnly;
             else if (codeBlock->replacement())
                 type = BaselineOSR;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to