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;