summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-02-03 09:55:33 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-02-03 09:55:33 +0100
commitcd44dc59cdfc39534aef4d417e9f3c412e3be139 (patch)
tree8d89889ba95ed6ec9322e733846cc9cce9d7dff1 /Source/JavaScriptCore/bytecode
parentd11f84f5b5cdc0d92a08af01b13472fdd5f9acb9 (diff)
downloadqtwebkit-cd44dc59cdfc39534aef4d417e9f3c412e3be139.tar.gz
Imported WebKit commit fce473cb4d55aa9fe9d0b0322a2fffecb731b961 (http://svn.webkit.org/repository/webkit/trunk@106560)
Diffstat (limited to 'Source/JavaScriptCore/bytecode')
-rw-r--r--Source/JavaScriptCore/bytecode/CallLinkInfo.h2
-rw-r--r--Source/JavaScriptCore/bytecode/CallLinkStatus.cpp47
-rw-r--r--Source/JavaScriptCore/bytecode/CallLinkStatus.h66
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp76
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.h79
-rw-r--r--Source/JavaScriptCore/bytecode/CodeOrigin.h24
-rw-r--r--Source/JavaScriptCore/bytecode/GetByIdStatus.cpp138
-rw-r--r--Source/JavaScriptCore/bytecode/GetByIdStatus.h82
-rw-r--r--Source/JavaScriptCore/bytecode/Instruction.h8
-rw-r--r--Source/JavaScriptCore/bytecode/MethodCallLinkStatus.cpp61
-rw-r--r--Source/JavaScriptCore/bytecode/MethodCallLinkStatus.h87
-rw-r--r--Source/JavaScriptCore/bytecode/Opcode.h53
-rw-r--r--Source/JavaScriptCore/bytecode/PredictedType.cpp7
-rw-r--r--Source/JavaScriptCore/bytecode/PredictedType.h61
-rw-r--r--Source/JavaScriptCore/bytecode/PutByIdStatus.cpp89
-rw-r--r--Source/JavaScriptCore/bytecode/PutByIdStatus.h106
-rw-r--r--Source/JavaScriptCore/bytecode/SamplingTool.h14
-rw-r--r--Source/JavaScriptCore/bytecode/StructureSet.h158
-rw-r--r--Source/JavaScriptCore/bytecode/StructureStubInfo.h3
19 files changed, 1042 insertions, 119 deletions
diff --git a/Source/JavaScriptCore/bytecode/CallLinkInfo.h b/Source/JavaScriptCore/bytecode/CallLinkInfo.h
index 8ec48e4e1..44d50a971 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkInfo.h
+++ b/Source/JavaScriptCore/bytecode/CallLinkInfo.h
@@ -72,7 +72,7 @@ struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
WriteBarrier<JSFunction> lastSeenCallee;
bool hasSeenShouldRepatch : 1;
bool isDFG : 1;
- CallType callType : 2;
+ CallType callType : 6;
unsigned bytecodeIndex;
bool isLinked() { return callee; }
diff --git a/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp b/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
new file mode 100644
index 000000000..f3fd5bb27
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CallLinkStatus.h"
+
+#include "CodeBlock.h"
+
+namespace JSC {
+
+CallLinkStatus CallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex)
+{
+ UNUSED_PARAM(profiledBlock);
+ UNUSED_PARAM(bytecodeIndex);
+#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
+ return CallLinkStatus(
+ profiledBlock->getCallLinkInfo(bytecodeIndex).lastSeenCallee.get(),
+ profiledBlock->couldTakeSlowCase(bytecodeIndex));
+#else
+ return CallLinkStatus(0, false);
+#endif
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/bytecode/CallLinkStatus.h b/Source/JavaScriptCore/bytecode/CallLinkStatus.h
new file mode 100644
index 000000000..e1c741016
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/CallLinkStatus.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CallLinkStatus_h
+#define CallLinkStatus_h
+
+namespace JSC {
+
+class JSFunction;
+class CodeBlock;
+
+class CallLinkStatus {
+public:
+ CallLinkStatus()
+ : m_callTarget(0)
+ , m_couldTakeSlowPath(false)
+ {
+ }
+
+ CallLinkStatus(JSFunction* callTarget, bool couldTakeSlowPath)
+ : m_callTarget(callTarget)
+ , m_couldTakeSlowPath(couldTakeSlowPath)
+ {
+ }
+
+ static CallLinkStatus computeFor(CodeBlock*, unsigned bytecodeIndex);
+
+ bool isSet() const { return !!m_callTarget; }
+
+ bool operator!() const { return !m_callTarget; }
+
+ bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
+
+ JSFunction* callTarget() const { return m_callTarget; }
+
+private:
+ JSFunction* m_callTarget;
+ bool m_couldTakeSlowPath;
+};
+
+} // namespace JSC
+
+#endif // CallLinkStatus_h
+
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 47745268c..4a953266e 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -78,7 +78,7 @@ static UString valueToSourceString(ExecState* exec, JSValue val)
return "0";
if (val.isString())
- return makeUString("\"", escapeQuotes(val.toString(exec)), "\"");
+ return makeUString("\"", escapeQuotes(val.toString(exec)->value(exec)), "\"");
return val.description();
}
@@ -180,7 +180,16 @@ void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vector<Instruction
int r1 = (++it)->u.operand;
int id0 = (++it)->u.operand;
printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
- it += 4;
+ it += 5;
+}
+
+void CodeBlock::printCallOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const
+{
+ int func = (++it)->u.operand;
+ int argCount = (++it)->u.operand;
+ int registerOffset = (++it)->u.operand;
+ printf("[%4d] %s\t %s, %d, %d\n", location, op, registerName(exec, func).data(), argCount, registerOffset);
+ it += 2;
}
void CodeBlock::printPutByIdOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const
@@ -522,7 +531,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
case op_convert_this: {
int r0 = (++it)->u.operand;
- printf("[%4d] convert_this %s\n", location, registerName(exec, r0).data());
+ printf("[%4d] convert_this\t %s\n", location, registerName(exec, r0).data());
break;
}
case op_new_object: {
@@ -734,6 +743,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r0 = (++it)->u.operand;
int id0 = (++it)->u.operand;
printf("[%4d] resolve\t\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
+ it++;
break;
}
case op_resolve_skip: {
@@ -741,13 +751,14 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int id0 = (++it)->u.operand;
int skipLevels = (++it)->u.operand;
printf("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), skipLevels);
+ it++;
break;
}
case op_resolve_global: {
int r0 = (++it)->u.operand;
int id0 = (++it)->u.operand;
printf("[%4d] resolve_global\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
- it += 2;
+ it += 3;
break;
}
case op_resolve_global_dynamic: {
@@ -757,6 +768,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
++it;
int depth = (++it)->u.operand;
printf("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth);
+ ++it;
break;
}
case op_get_scoped_var: {
@@ -764,6 +776,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int index = (++it)->u.operand;
int skipLevels = (++it)->u.operand;
printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(exec, r0).data(), index, skipLevels);
+ it++;
break;
}
case op_put_scoped_var: {
@@ -777,6 +790,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r0 = (++it)->u.operand;
int index = (++it)->u.operand;
printf("[%4d] get_global_var\t %s, %d\n", location, registerName(exec, r0).data(), index);
+ it++;
break;
}
case op_put_global_var: {
@@ -790,6 +804,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int id0 = (++it)->u.operand;
int isStrict = (++it)->u.operand;
printf("[%4d] resolve_base%s\t %s, %s\n", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
+ it++;
break;
}
case op_ensure_property_exists: {
@@ -803,6 +818,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r1 = (++it)->u.operand;
int id0 = (++it)->u.operand;
printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
+ it++;
break;
}
case op_resolve_with_this: {
@@ -810,6 +826,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r1 = (++it)->u.operand;
int id0 = (++it)->u.operand;
printf("[%4d] resolve_with_this %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
+ it++;
break;
}
case op_get_by_id: {
@@ -885,18 +902,12 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
printPutByIdOp(exec, location, it, "put_by_id_generic");
break;
}
- case op_put_getter: {
+ case op_put_getter_setter: {
int r0 = (++it)->u.operand;
int id0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- printf("[%4d] put_getter\t %s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
- break;
- }
- case op_put_setter: {
- int r0 = (++it)->u.operand;
- int id0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- printf("[%4d] put_setter\t %s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
+ int r2 = (++it)->u.operand;
+ printf("[%4d] put_getter_setter\t %s, %s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
break;
}
case op_method_check: {
@@ -915,6 +926,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
+ it++;
break;
}
case op_get_argument_by_val: {
@@ -922,6 +934,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
printf("[%4d] get_argument_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
+ ++it;
break;
}
case op_get_by_pname: {
@@ -1119,17 +1132,11 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
break;
}
case op_call: {
- int func = (++it)->u.operand;
- int argCount = (++it)->u.operand;
- int registerOffset = (++it)->u.operand;
- printf("[%4d] call\t\t %s, %d, %d\n", location, registerName(exec, func).data(), argCount, registerOffset);
+ printCallOp(exec, location, it, "call");
break;
}
case op_call_eval: {
- int func = (++it)->u.operand;
- int argCount = (++it)->u.operand;
- int registerOffset = (++it)->u.operand;
- printf("[%4d] call_eval\t %s, %d, %d\n", location, registerName(exec, func).data(), argCount, registerOffset);
+ printCallOp(exec, location, it, "call_eval");
break;
}
case op_call_varargs: {
@@ -1148,7 +1155,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
case op_tear_off_arguments: {
int r0 = (++it)->u.operand;
- printf("[%4d] tear_off_arguments\t %s\n", location, registerName(exec, r0).data());
+ printf("[%4d] tear_off_arguments %s\n", location, registerName(exec, r0).data());
break;
}
case op_ret: {
@@ -1159,6 +1166,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
case op_call_put_result: {
int r0 = (++it)->u.operand;
printf("[%4d] op_call_put_result\t\t %s\n", location, registerName(exec, r0).data());
+ it++;
break;
}
case op_ret_object_or_this: {
@@ -1168,10 +1176,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
break;
}
case op_construct: {
- int func = (++it)->u.operand;
- int argCount = (++it)->u.operand;
- int registerOffset = (++it)->u.operand;
- printf("[%4d] construct\t %s, %d, %d\n", location, registerName(exec, func).data(), argCount, registerOffset);
+ printCallOp(exec, location, it, "construct");
break;
}
case op_strcat: {
@@ -1446,6 +1451,9 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab)
, m_speculativeFailCounter(0)
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
+#if ENABLE(JIT)
+ , m_canCompileWithDFGState(CompileWithDFGUnset)
+#endif
{
setNumParameters(other.numParameters());
optimizeAfterWarmUp();
@@ -2054,6 +2062,16 @@ void CodeBlock::createActivation(CallFrame* callFrame)
callFrame->uncheckedR(activationRegister()) = JSValue(activation);
callFrame->setScopeChain(callFrame->scopeChain()->push(activation));
}
+
+unsigned CodeBlock::addOrFindConstant(JSValue v)
+{
+ unsigned numberOfConstants = numberOfConstantRegisters();
+ for (unsigned i = 0; i < numberOfConstants; ++i) {
+ if (getConstant(FirstConstantRegisterIndex + i) == v)
+ return i;
+ }
+ return addConstant(v);
+}
#if ENABLE(JIT)
void CodeBlock::unlinkCalls()
@@ -2154,17 +2172,17 @@ JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, ScopeChainNode* s
return error;
}
-bool ProgramCodeBlock::canCompileWithDFG()
+bool ProgramCodeBlock::canCompileWithDFGInternal()
{
return DFG::canCompileProgram(this);
}
-bool EvalCodeBlock::canCompileWithDFG()
+bool EvalCodeBlock::canCompileWithDFGInternal()
{
return DFG::canCompileEval(this);
}
-bool FunctionCodeBlock::canCompileWithDFG()
+bool FunctionCodeBlock::canCompileWithDFGInternal()
{
if (m_isConstructor)
return DFG::canCompileFunctionForConstruct(this);
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index c440c72e1..23d6a6b6d 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -94,7 +94,7 @@ namespace JSC {
Heap* m_heap;
public:
- virtual ~CodeBlock();
+ JS_EXPORT_PRIVATE virtual ~CodeBlock();
int numParameters() const { return m_numParameters; }
void setNumParameters(int newValue);
@@ -388,7 +388,22 @@ namespace JSC {
virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*) = 0;
virtual void jettison() = 0;
virtual CodeBlock* replacement() = 0;
- virtual bool canCompileWithDFG() = 0;
+
+ enum CompileWithDFGState {
+ CompileWithDFGFalse,
+ CompileWithDFGTrue,
+ CompileWithDFGUnset
+ };
+
+ virtual bool canCompileWithDFGInternal() = 0;
+ bool canCompileWithDFG()
+ {
+ bool result = canCompileWithDFGInternal();
+ m_canCompileWithDFGState = result ? CompileWithDFGTrue : CompileWithDFGFalse;
+ return result;
+ }
+ CompileWithDFGState canCompileWithDFGState() { return m_canCompileWithDFGState; }
+
bool hasOptimizedReplacement()
{
ASSERT(getJITType() == JITCode::BaselineJIT);
@@ -521,6 +536,11 @@ namespace JSC {
{
ValueProfile* result = WTF::genericBinarySearch<ValueProfile, int, getValueProfileBytecodeOffset>(m_valueProfiles, m_valueProfiles.size(), bytecodeOffset);
ASSERT(result->m_bytecodeOffset != -1);
+ ASSERT(!hasInstructions()
+ || instructions()[bytecodeOffset + opcodeLength(
+ m_globalData->interpreter->getOpcodeID(
+ instructions()[
+ bytecodeOffset].u.opcode)) - 1].u.profile == result);
return result;
}
@@ -664,10 +684,22 @@ namespace JSC {
return m_rareData && !!m_rareData->m_codeOrigins.size();
}
- CodeOrigin codeOriginForReturn(ReturnAddressPtr returnAddress)
+ bool codeOriginForReturn(ReturnAddressPtr returnAddress, CodeOrigin& codeOrigin)
{
- ASSERT(hasCodeOrigins());
- return binarySearch<CodeOriginAtCallReturnOffset, unsigned, getCallReturnOffsetForCodeOrigin>(codeOrigins().begin(), codeOrigins().size(), getJITCode().offsetOf(returnAddress.value()))->codeOrigin;
+ if (!hasCodeOrigins())
+ return false;
+ unsigned offset = getJITCode().offsetOf(returnAddress.value());
+ CodeOriginAtCallReturnOffset* entry = binarySearch<CodeOriginAtCallReturnOffset, unsigned, getCallReturnOffsetForCodeOrigin>(codeOrigins().begin(), codeOrigins().size(), offset, WTF::KeyMustNotBePresentInArray);
+ if (entry->callReturnOffset != offset)
+ return false;
+ codeOrigin = entry->codeOrigin;
+ return true;
+ }
+
+ CodeOrigin codeOrigin(unsigned index)
+ {
+ ASSERT(m_rareData);
+ return m_rareData->m_codeOrigins[index].codeOrigin;
}
bool addFrequentExitSite(const DFG::FrequentExitSite& site)
@@ -686,11 +718,14 @@ namespace JSC {
Identifier& identifier(int index) { return m_identifiers[index]; }
size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
- void addConstant(JSValue v)
+ unsigned addConstant(JSValue v)
{
+ unsigned result = m_constantRegisters.size();
m_constantRegisters.append(WriteBarrier<Unknown>());
m_constantRegisters.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), v);
+ return result;
}
+ unsigned addOrFindConstant(JSValue);
WriteBarrier<Unknown>& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
@@ -780,7 +815,7 @@ namespace JSC {
// Functions for controlling when tiered compilation kicks in. This
// controls both when the optimizing compiler is invoked and when OSR
// entry happens. Two triggers exist: the loop trigger and the return
- // trigger. In either case, when an addition to m_executeCounter
+ // trigger. In either case, when an addition to m_jitExecuteCounter
// causes it to become non-negative, the optimizing compiler is
// invoked. This includes a fast check to see if this CodeBlock has
// already been optimized (i.e. replacement() returns a CodeBlock
@@ -821,14 +856,14 @@ namespace JSC {
return Options::executionCounterValueForOptimizeAfterLongWarmUp << reoptimizationRetryCounter();
}
- int32_t* addressOfExecuteCounter()
+ int32_t* addressOfJITExecuteCounter()
{
- return &m_executeCounter;
+ return &m_jitExecuteCounter;
}
- static ptrdiff_t offsetOfExecuteCounter() { return OBJECT_OFFSETOF(CodeBlock, m_executeCounter); }
+ static ptrdiff_t offsetOfJITExecuteCounter() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter); }
- int32_t executeCounter() const { return m_executeCounter; }
+ int32_t jitExecuteCounter() const { return m_jitExecuteCounter; }
unsigned optimizationDelayCounter() const { return m_optimizationDelayCounter; }
@@ -837,7 +872,7 @@ namespace JSC {
// expensive than executing baseline code.
void optimizeNextInvocation()
{
- m_executeCounter = Options::executionCounterValueForOptimizeNextInvocation;
+ m_jitExecuteCounter = Options::executionCounterValueForOptimizeNextInvocation;
}
// Call this to prevent optimization from happening again. Note that
@@ -847,7 +882,7 @@ namespace JSC {
// the future as well.
void dontOptimizeAnytimeSoon()
{
- m_executeCounter = Options::executionCounterValueForDontOptimizeAnytimeSoon;
+ m_jitExecuteCounter = Options::executionCounterValueForDontOptimizeAnytimeSoon;
}
// Call this to reinitialize the counter to its starting state,
@@ -858,14 +893,14 @@ namespace JSC {
// counter that this corresponds to is also available directly.
void optimizeAfterWarmUp()
{
- m_executeCounter = counterValueForOptimizeAfterWarmUp();
+ m_jitExecuteCounter = counterValueForOptimizeAfterWarmUp();
}
// Call this to force an optimization trigger to fire only after
// a lot of warm-up.
void optimizeAfterLongWarmUp()
{
- m_executeCounter = counterValueForOptimizeAfterLongWarmUp();
+ m_jitExecuteCounter = counterValueForOptimizeAfterLongWarmUp();
}
// Call this to cause an optimization trigger to fire soon, but
@@ -888,7 +923,7 @@ namespace JSC {
// in the baseline code.
void optimizeSoon()
{
- m_executeCounter = Options::executionCounterValueForOptimizeSoon << reoptimizationRetryCounter();
+ m_jitExecuteCounter = Options::executionCounterValueForOptimizeSoon << reoptimizationRetryCounter();
}
// The speculative JIT tracks its success rate, so that we can
@@ -989,6 +1024,7 @@ namespace JSC {
void printBinaryOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
void printConditionalJump(ExecState*, const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator&, int location, const char* op) const;
void printGetByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
+ void printCallOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
void printPutByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
#endif
void visitStructures(SlotVisitor&, Instruction* vPC) const;
@@ -1129,7 +1165,7 @@ namespace JSC {
OwnPtr<CodeBlock> m_alternative;
- int32_t m_executeCounter;
+ int32_t m_jitExecuteCounter;
uint32_t m_speculativeSuccessCounter;
uint32_t m_speculativeFailCounter;
uint8_t m_optimizationDelayCounter;
@@ -1169,6 +1205,9 @@ namespace JSC {
friend void WTF::deleteOwnedPtr<RareData>(RareData*);
#endif
OwnPtr<RareData> m_rareData;
+#if ENABLE(JIT)
+ CompileWithDFGState m_canCompileWithDFGState;
+#endif
};
// Program code is not marked by any function, so we make the global object
@@ -1208,7 +1247,7 @@ namespace JSC {
virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
virtual void jettison();
virtual CodeBlock* replacement();
- virtual bool canCompileWithDFG();
+ virtual bool canCompileWithDFGInternal();
#endif
};
@@ -1242,7 +1281,7 @@ namespace JSC {
virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
virtual void jettison();
virtual CodeBlock* replacement();
- virtual bool canCompileWithDFG();
+ virtual bool canCompileWithDFGInternal();
#endif
private:
@@ -1279,7 +1318,7 @@ namespace JSC {
virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*);
virtual void jettison();
virtual CodeBlock* replacement();
- virtual bool canCompileWithDFG();
+ virtual bool canCompileWithDFGInternal();
#endif
};
diff --git a/Source/JavaScriptCore/bytecode/CodeOrigin.h b/Source/JavaScriptCore/bytecode/CodeOrigin.h
index 7b6ce7d48..25a116c55 100644
--- a/Source/JavaScriptCore/bytecode/CodeOrigin.h
+++ b/Source/JavaScriptCore/bytecode/CodeOrigin.h
@@ -38,29 +38,37 @@ class ExecutableBase;
class JSFunction;
struct CodeOrigin {
- uint32_t bytecodeIndex;
+ // Bytecode offset that you'd use to re-execute this instruction.
+ unsigned bytecodeIndex : 29;
+ // Bytecode offset corresponding to the opcode that gives the result (needed to handle
+ // op_call/op_call_put_result and op_method_check/op_get_by_id).
+ unsigned valueProfileOffset : 3;
+
InlineCallFrame* inlineCallFrame;
CodeOrigin()
: bytecodeIndex(std::numeric_limits<uint32_t>::max())
+ , valueProfileOffset(0)
, inlineCallFrame(0)
{
}
- explicit CodeOrigin(uint32_t bytecodeIndex)
- : bytecodeIndex(bytecodeIndex)
- , inlineCallFrame(0)
- {
- }
-
- explicit CodeOrigin(uint32_t bytecodeIndex, InlineCallFrame* inlineCallFrame)
+ explicit CodeOrigin(unsigned bytecodeIndex, InlineCallFrame* inlineCallFrame = 0, unsigned valueProfileOffset = 0)
: bytecodeIndex(bytecodeIndex)
+ , valueProfileOffset(valueProfileOffset)
, inlineCallFrame(inlineCallFrame)
{
+ ASSERT(bytecodeIndex < (1u << 29));
+ ASSERT(valueProfileOffset < (1u << 3));
}
bool isSet() const { return bytecodeIndex != std::numeric_limits<uint32_t>::max(); }
+ unsigned bytecodeIndexForValueProfile() const
+ {
+ return bytecodeIndex + valueProfileOffset;
+ }
+
// The inline depth is the depth of the inline stack, so 1 = not inlined,
// 2 = inlined one deep, etc.
unsigned inlineDepth() const;
diff --git a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
new file mode 100644
index 000000000..5eff1d4a0
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GetByIdStatus.h"
+
+#include "CodeBlock.h"
+
+namespace JSC {
+
+GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
+{
+ UNUSED_PARAM(profiledBlock);
+ UNUSED_PARAM(bytecodeIndex);
+ UNUSED_PARAM(ident);
+#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
+ // First check if it makes either calls, in which case we want to be super careful, or
+ // if it's not set at all, in which case we punt.
+ StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex);
+ if (!stubInfo.seen)
+ return GetByIdStatus(NoInformation, StructureSet(), notFound);
+
+ PolymorphicAccessStructureList* list;
+ int listSize;
+ switch (stubInfo.accessType) {
+ case access_get_by_id_self_list:
+ list = stubInfo.u.getByIdSelfList.structureList;
+ listSize = stubInfo.u.getByIdSelfList.listSize;
+ break;
+ case access_get_by_id_proto_list:
+ list = stubInfo.u.getByIdProtoList.structureList;
+ listSize = stubInfo.u.getByIdProtoList.listSize;
+ break;
+ default:
+ list = 0;
+ listSize = 0;
+ break;
+ }
+ for (int i = 0; i < listSize; ++i) {
+ if (!list->list[i].isDirect)
+ return GetByIdStatus(MakesCalls, StructureSet(), notFound);
+ }
+
+ // Next check if it takes slow case, in which case we want to be kind of careful.
+ if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
+ return GetByIdStatus(TakesSlowPath, StructureSet(), notFound);
+
+ // Finally figure out if we can derive an access strategy.
+ GetByIdStatus result;
+ switch (stubInfo.accessType) {
+ case access_unset:
+ return GetByIdStatus(NoInformation, StructureSet(), notFound);
+
+ case access_get_by_id_self: {
+ Structure* structure = stubInfo.u.getByIdSelf.baseObjectStructure.get();
+ result.m_offset = structure->get(*profiledBlock->globalData(), ident);
+
+ if (result.m_offset != notFound)
+ result.m_structureSet.add(structure);
+
+ if (result.m_offset != notFound)
+ ASSERT(result.m_structureSet.size());
+ break;
+ }
+
+ case access_get_by_id_self_list: {
+ PolymorphicAccessStructureList* list = stubInfo.u.getByIdProtoList.structureList;
+ unsigned size = stubInfo.u.getByIdProtoList.listSize;
+ for (unsigned i = 0; i < size; ++i) {
+ ASSERT(list->list[i].isDirect);
+
+ Structure* structure = list->list[i].base.get();
+ if (result.m_structureSet.contains(structure))
+ continue;
+
+ size_t myOffset = structure->get(*profiledBlock->globalData(), ident);
+
+ if (myOffset == notFound) {
+ result.m_offset = notFound;
+ break;
+ }
+
+ if (!i)
+ result.m_offset = myOffset;
+ else if (result.m_offset != myOffset) {
+ result.m_offset = notFound;
+ break;
+ }
+
+ result.m_structureSet.add(structure);
+ }
+
+ if (result.m_offset != notFound)
+ ASSERT(result.m_structureSet.size());
+ break;
+ }
+
+ default:
+ ASSERT(result.m_offset == notFound);
+ break;
+ }
+
+ if (result.m_offset == notFound) {
+ result.m_state = TakesSlowPath;
+ result.m_structureSet.clear();
+ } else
+ result.m_state = SimpleDirect;
+
+ return result;
+#else // ENABLE(JIT)
+ return GetByIdStatus(NoInformation, StructureSet(), notFound);
+#endif // ENABLE(JIT)
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/bytecode/GetByIdStatus.h b/Source/JavaScriptCore/bytecode/GetByIdStatus.h
new file mode 100644
index 000000000..00e50e76d
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/GetByIdStatus.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GetByIdStatus_h
+#define GetByIdStatus_h
+
+#include "StructureSet.h"
+#include <wtf/NotFound.h>
+
+namespace JSC {
+
+class CodeBlock;
+class Identifier;
+
+class GetByIdStatus {
+public:
+ enum State {
+ NoInformation, // It's uncached so we have no information.
+ SimpleDirect, // It's cached for a direct access to a known object property.
+ TakesSlowPath, // It's known to often take slow path.
+ MakesCalls // It's known to take paths that make calls.
+ };
+
+ GetByIdStatus()
+ : m_state(NoInformation)
+ , m_offset(notFound)
+ {
+ }
+
+ GetByIdStatus(State state, const StructureSet& structureSet, size_t offset)
+ : m_state(state)
+ , m_structureSet(structureSet)
+ , m_offset(offset)
+ {
+ ASSERT((state == SimpleDirect) == (offset != notFound));
+ }
+
+ static GetByIdStatus computeFor(CodeBlock*, unsigned bytecodeIndex, Identifier&);
+
+ State state() const { return m_state; }
+
+ bool isSet() const { return m_state != NoInformation; }
+ bool operator!() const { return !isSet(); }
+ bool isSimpleDirect() const { return m_state == SimpleDirect; }
+ bool takesSlowPath() const { return m_state == TakesSlowPath || m_state == MakesCalls; }
+ bool makesCalls() const { return m_state == MakesCalls; }
+
+ const StructureSet& structureSet() const { return m_structureSet; }
+ size_t offset() const { return m_offset; }
+
+private:
+ State m_state;
+ StructureSet m_structureSet;
+ size_t m_offset;
+};
+
+} // namespace JSC
+
+#endif // PropertyAccessStatus_h
+
diff --git a/Source/JavaScriptCore/bytecode/Instruction.h b/Source/JavaScriptCore/bytecode/Instruction.h
index 7e4413065..92118eeb2 100644
--- a/Source/JavaScriptCore/bytecode/Instruction.h
+++ b/Source/JavaScriptCore/bytecode/Instruction.h
@@ -48,6 +48,7 @@ namespace JSC {
class JSCell;
class Structure;
class StructureChain;
+ struct ValueProfile;
#if ENABLE(JIT)
typedef MacroAssemblerCodeRef PolymorphicAccessStructureListStubRoutineType;
@@ -99,6 +100,10 @@ namespace JSC {
}
} list[POLYMORPHIC_LIST_CACHE_SIZE];
+ PolymorphicAccessStructureList()
+ {
+ }
+
PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, bool isDirect)
{
list[0].set(globalData, owner, stubRoutine, firstBase, isDirect);
@@ -176,6 +181,8 @@ namespace JSC {
}
Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
+
+ Instruction(ValueProfile* profile) { u.profile = profile; }
union {
Opcode opcode;
@@ -184,6 +191,7 @@ namespace JSC {
WriteBarrierBase<StructureChain> structureChain;
WriteBarrierBase<JSCell> jsCell;
PropertySlot::GetValueFunc getterFunc;
+ ValueProfile* profile;
} u;
private:
diff --git a/Source/JavaScriptCore/bytecode/MethodCallLinkStatus.cpp b/Source/JavaScriptCore/bytecode/MethodCallLinkStatus.cpp
new file mode 100644
index 000000000..e7d721c29
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/MethodCallLinkStatus.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MethodCallLinkStatus.h"
+
+#include "CodeBlock.h"
+
+namespace JSC {
+
+MethodCallLinkStatus MethodCallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex)
+{
+ UNUSED_PARAM(profiledBlock);
+ UNUSED_PARAM(bytecodeIndex);
+#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
+ MethodCallLinkInfo& methodCall = profiledBlock->getMethodCallLinkInfo(bytecodeIndex);
+
+ if (!methodCall.seen || !methodCall.cachedStructure)
+ return MethodCallLinkStatus();
+
+ if (methodCall.cachedPrototype.get() == profiledBlock->globalObject()->methodCallDummy()) {
+ return MethodCallLinkStatus(
+ methodCall.cachedStructure.get(),
+ 0,
+ methodCall.cachedFunction.get(),
+ 0);
+ }
+
+ return MethodCallLinkStatus(
+ methodCall.cachedStructure.get(),
+ methodCall.cachedPrototypeStructure.get(),
+ methodCall.cachedFunction.get(),
+ methodCall.cachedPrototype.get());
+#else // ENABLE(JIT)
+ return MethodCallLinkStatus();
+#endif // ENABLE(JIT)
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/MethodCallLinkStatus.h b/Source/JavaScriptCore/bytecode/MethodCallLinkStatus.h
new file mode 100644
index 000000000..c3d11a1d8
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/MethodCallLinkStatus.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MethodCallLinkStatus_h
+#define MethodCallLinkStatus_h
+
+namespace JSC {
+
+class CodeBlock;
+class JSObject;
+class Structure;
+
+class MethodCallLinkStatus {
+public:
+ MethodCallLinkStatus()
+ : m_structure(0)
+ , m_prototypeStructure(0)
+ , m_function(0)
+ , m_prototype(0)
+ {
+ }
+
+ MethodCallLinkStatus(
+ Structure* structure,
+ Structure* prototypeStructure,
+ JSObject* function,
+ JSObject* prototype)
+ : m_structure(structure)
+ , m_prototypeStructure(prototypeStructure)
+ , m_function(function)
+ , m_prototype(prototype)
+ {
+ if (!m_function) {
+ ASSERT(!m_structure);
+ ASSERT(!m_prototypeStructure);
+ ASSERT(!m_prototype);
+ } else
+ ASSERT(m_structure);
+
+ ASSERT(!m_prototype == !m_prototypeStructure);
+ }
+
+ static MethodCallLinkStatus computeFor(CodeBlock*, unsigned bytecodeIndex);
+
+ bool isSet() const { return !!m_function; }
+ bool operator!() const { return !m_function; }
+
+ bool needsPrototypeCheck() const { return !!m_prototype; }
+
+ Structure* structure() { return m_structure; }
+ Structure* prototypeStructure() { return m_prototypeStructure; }
+ JSObject* function() const { return m_function; }
+ JSObject* prototype() const { return m_prototype; }
+
+private:
+ Structure* m_structure;
+ Structure* m_prototypeStructure;
+ JSObject* m_function;
+ JSObject* m_prototype;
+};
+
+} // namespace JSC
+
+#endif // MethodCallLinkStatus_h
+
diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h
index 4801e4c32..57633a338 100644
--- a/Source/JavaScriptCore/bytecode/Opcode.h
+++ b/Source/JavaScriptCore/bytecode/Opcode.h
@@ -95,45 +95,44 @@ namespace JSC {
macro(op_is_function, 3) \
macro(op_in, 4) \
\
- macro(op_resolve, 3) \
- macro(op_resolve_skip, 4) \
- macro(op_resolve_global, 5) \
- macro(op_resolve_global_dynamic, 6) \
- macro(op_get_scoped_var, 4) \
+ macro(op_resolve, 4) /* has value profiling */ \
+ macro(op_resolve_skip, 5) /* has value profiling */ \
+ macro(op_resolve_global, 6) /* has value profiling */ \
+ macro(op_resolve_global_dynamic, 7) /* has value profiling */ \
+ macro(op_get_scoped_var, 5) /* has value profiling */ \
macro(op_put_scoped_var, 4) \
- macro(op_get_global_var, 3) \
+ macro(op_get_global_var, 4) /* has value profiling */ \
macro(op_put_global_var, 3) \
- macro(op_resolve_base, 4) \
+ macro(op_resolve_base, 5) /* has value profiling */ \
macro(op_ensure_property_exists, 3) \
- macro(op_resolve_with_base, 4) \
- macro(op_resolve_with_this, 4) \
- macro(op_get_by_id, 8) \
- macro(op_get_by_id_self, 8) \
- macro(op_get_by_id_proto, 8) \
- macro(op_get_by_id_chain, 8) \
- macro(op_get_by_id_getter_self, 8) \
- macro(op_get_by_id_getter_proto, 8) \
- macro(op_get_by_id_getter_chain, 8) \
- macro(op_get_by_id_custom_self, 8) \
- macro(op_get_by_id_custom_proto, 8) \
- macro(op_get_by_id_custom_chain, 8) \
- macro(op_get_by_id_generic, 8) \
- macro(op_get_array_length, 8) \
- macro(op_get_string_length, 8) \
+ macro(op_resolve_with_base, 5) /* has value profiling */ \
+ macro(op_resolve_with_this, 5) /* has value profiling */ \
+ macro(op_get_by_id, 9) /* has value profiling */ \
+ macro(op_get_by_id_self, 9) /* has value profiling */ \
+ macro(op_get_by_id_proto, 9) /* has value profiling */ \
+ macro(op_get_by_id_chain, 9) /* has value profiling */ \
+ macro(op_get_by_id_getter_self, 9) /* has value profiling */ \
+ macro(op_get_by_id_getter_proto, 9) /* has value profiling */ \
+ macro(op_get_by_id_getter_chain, 9) /* has value profiling */ \
+ macro(op_get_by_id_custom_self, 9) /* has value profiling */ \
+ macro(op_get_by_id_custom_proto, 9) /* has value profiling */ \
+ macro(op_get_by_id_custom_chain, 9) /* has value profiling */ \
+ macro(op_get_by_id_generic, 9) /* has value profiling */ \
+ macro(op_get_array_length, 9) /* has value profiling */ \
+ macro(op_get_string_length, 9) /* has value profiling */ \
macro(op_get_arguments_length, 4) \
macro(op_put_by_id, 9) \
macro(op_put_by_id_transition, 9) \
macro(op_put_by_id_replace, 9) \
macro(op_put_by_id_generic, 9) \
macro(op_del_by_id, 4) \
- macro(op_get_by_val, 4) \
- macro(op_get_argument_by_val, 4) \
+ macro(op_get_by_val, 5) /* has value profiling */ \
+ macro(op_get_argument_by_val, 5) /* must be the same size as op_get_by_val */ \
macro(op_get_by_pname, 7) \
macro(op_put_by_val, 4) \
macro(op_del_by_val, 4) \
macro(op_put_by_index, 4) \
- macro(op_put_getter, 4) \
- macro(op_put_setter, 4) \
+ macro(op_put_getter_setter, 5) \
\
macro(op_jmp, 2) \
macro(op_jtrue, 3) \
@@ -170,7 +169,7 @@ namespace JSC {
macro(op_tear_off_activation, 3) \
macro(op_tear_off_arguments, 2) \
macro(op_ret, 2) \
- macro(op_call_put_result, 2) \
+ macro(op_call_put_result, 3) /* has value profiling */ \
macro(op_ret_object_or_this, 3) \
macro(op_method_check, 1) \
\
diff --git a/Source/JavaScriptCore/bytecode/PredictedType.cpp b/Source/JavaScriptCore/bytecode/PredictedType.cpp
index 9356390a9..4b07ff446 100644
--- a/Source/JavaScriptCore/bytecode/PredictedType.cpp
+++ b/Source/JavaScriptCore/bytecode/PredictedType.cpp
@@ -92,6 +92,11 @@ const char* predictionToString(PredictedType value)
ptr.strcat("Uint8array");
else
isTop = false;
+
+ if (value & PredictUint8ClampedArray)
+ ptr.strcat("Uint8clampedarray");
+ else
+ isTop = false;
if (value & PredictUint16Array)
ptr.strcat("Uint16array");
@@ -184,6 +189,8 @@ PredictedType predictionFromClassInfo(const ClassInfo* classInfo)
return PredictInt32Array;
case TypedArrayUint8:
return PredictUint8Array;
+ case TypedArrayUint8Clamped:
+ return PredictUint8ClampedArray;
case TypedArrayUint16:
return PredictUint16Array;
case TypedArrayUint32:
diff --git a/Source/JavaScriptCore/bytecode/PredictedType.h b/Source/JavaScriptCore/bytecode/PredictedType.h
index 3ec03924a..47583361d 100644
--- a/Source/JavaScriptCore/bytecode/PredictedType.h
+++ b/Source/JavaScriptCore/bytecode/PredictedType.h
@@ -36,33 +36,34 @@ namespace JSC {
class Structure;
typedef uint32_t PredictedType;
-static const PredictedType PredictNone = 0x00000000; // We don't know anything yet.
-static const PredictedType PredictFinalObject = 0x00000001; // It's definitely a JSFinalObject.
-static const PredictedType PredictArray = 0x00000002; // It's definitely a JSArray.
-static const PredictedType PredictByteArray = 0x00000004; // It's definitely a JSByteArray or one of its subclasses.
-static const PredictedType PredictFunction = 0x00000008; // It's definitely a JSFunction or one of its subclasses.
-static const PredictedType PredictInt8Array = 0x00000010; // It's definitely an Int8Array or one of its subclasses.
-static const PredictedType PredictInt16Array = 0x00000020; // It's definitely an Int16Array or one of its subclasses.
-static const PredictedType PredictInt32Array = 0x00000040; // It's definitely an Int32Array or one of its subclasses.
-static const PredictedType PredictUint8Array = 0x00000080; // It's definitely an Uint8Array or one of its subclasses.
-static const PredictedType PredictUint16Array = 0x00000100; // It's definitely an Uint16Array or one of its subclasses.
-static const PredictedType PredictUint32Array = 0x00000200; // It's definitely an Uint32Array or one of its subclasses.
-static const PredictedType PredictFloat32Array = 0x00000400; // It's definitely an Uint16Array or one of its subclasses.
-static const PredictedType PredictFloat64Array = 0x00000800; // It's definitely an Uint16Array or one of its subclasses.
-static const PredictedType PredictObjectOther = 0x00001000; // It's definitely an object but not JSFinalObject, JSArray, JSByteArray, or JSFunction.
-static const PredictedType PredictObjectMask = 0x00001fff; // Bitmask used for testing for any kind of object prediction.
-static const PredictedType PredictString = 0x00002000; // It's definitely a JSString.
-static const PredictedType PredictCellOther = 0x00004000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString.
-static const PredictedType PredictCell = 0x00007fff; // It's definitely a JSCell.
-static const PredictedType PredictInt32 = 0x00008000; // It's definitely an Int32.
-static const PredictedType PredictDoubleReal = 0x00010000; // It's definitely a non-NaN double.
-static const PredictedType PredictDoubleNaN = 0x00020000; // It's definitely a NaN.
-static const PredictedType PredictDouble = 0x00030000; // It's either a non-NaN or a NaN double.
-static const PredictedType PredictNumber = 0x00038000; // It's either an Int32 or a Double.
-static const PredictedType PredictBoolean = 0x00040000; // It's definitely a Boolean.
-static const PredictedType PredictOther = 0x40000000; // It's definitely none of the above.
-static const PredictedType PredictTop = 0x7fffffff; // It can be any of the above.
-static const PredictedType FixedIndexedStorageMask = PredictByteArray | PredictInt8Array | PredictInt16Array | PredictInt32Array | PredictUint8Array | PredictUint16Array | PredictUint32Array | PredictFloat32Array | PredictFloat64Array;
+static const PredictedType PredictNone = 0x00000000; // We don't know anything yet.
+static const PredictedType PredictFinalObject = 0x00000001; // It's definitely a JSFinalObject.
+static const PredictedType PredictArray = 0x00000002; // It's definitely a JSArray.
+static const PredictedType PredictByteArray = 0x00000004; // It's definitely a JSByteArray or one of its subclasses.
+static const PredictedType PredictFunction = 0x00000008; // It's definitely a JSFunction or one of its subclasses.
+static const PredictedType PredictInt8Array = 0x00000010; // It's definitely an Int8Array or one of its subclasses.
+static const PredictedType PredictInt16Array = 0x00000020; // It's definitely an Int16Array or one of its subclasses.
+static const PredictedType PredictInt32Array = 0x00000040; // It's definitely an Int32Array or one of its subclasses.
+static const PredictedType PredictUint8Array = 0x00000080; // It's definitely an Uint8Array or one of its subclasses.
+static const PredictedType PredictUint8ClampedArray = 0x00000100; // It's definitely an Uint8ClampedArray or one of its subclasses.
+static const PredictedType PredictUint16Array = 0x00000200; // It's definitely an Uint16Array or one of its subclasses.
+static const PredictedType PredictUint32Array = 0x00000400; // It's definitely an Uint32Array or one of its subclasses.
+static const PredictedType PredictFloat32Array = 0x00000800; // It's definitely an Uint16Array or one of its subclasses.
+static const PredictedType PredictFloat64Array = 0x00001000; // It's definitely an Uint16Array or one of its subclasses.
+static const PredictedType PredictObjectOther = 0x00002000; // It's definitely an object but not JSFinalObject, JSArray, JSByteArray, or JSFunction.
+static const PredictedType PredictObjectMask = 0x00003fff; // Bitmask used for testing for any kind of object prediction.
+static const PredictedType PredictString = 0x00004000; // It's definitely a JSString.
+static const PredictedType PredictCellOther = 0x00008000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString.
+static const PredictedType PredictCell = 0x0000ffff; // It's definitely a JSCell.
+static const PredictedType PredictInt32 = 0x00010000; // It's definitely an Int32.
+static const PredictedType PredictDoubleReal = 0x00020000; // It's definitely a non-NaN double.
+static const PredictedType PredictDoubleNaN = 0x00040000; // It's definitely a NaN.
+static const PredictedType PredictDouble = 0x00060000; // It's either a non-NaN or a NaN double.
+static const PredictedType PredictNumber = 0x00070000; // It's either an Int32 or a Double.
+static const PredictedType PredictBoolean = 0x00080000; // It's definitely a Boolean.
+static const PredictedType PredictOther = 0x40000000; // It's definitely none of the above.
+static const PredictedType PredictTop = 0x7fffffff; // It can be any of the above.
+static const PredictedType FixedIndexedStorageMask = PredictByteArray | PredictInt8Array | PredictInt16Array | PredictInt32Array | PredictUint8Array | PredictUint8ClampedArray | PredictUint16Array | PredictUint32Array | PredictFloat32Array | PredictFloat64Array;
typedef bool (*PredictionChecker)(PredictedType);
@@ -131,6 +132,11 @@ inline bool isUint8ArrayPrediction(PredictedType value)
return value == PredictUint8Array;
}
+inline bool isUint8ClampedArrayPrediction(PredictedType value)
+{
+ return value == PredictUint8ClampedArray;
+}
+
inline bool isUint16ArrayPrediction(PredictedType value)
{
return value == PredictUint16Array;
@@ -161,6 +167,7 @@ inline bool isActionableMutableArrayPrediction(PredictedType value)
#endif
|| isInt32ArrayPrediction(value)
|| isUint8ArrayPrediction(value)
+ || isUint8ClampedArrayPrediction(value)
|| isUint16ArrayPrediction(value)
|| isUint32ArrayPrediction(value)
#if CPU(X86) || CPU(X86_64)
diff --git a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
new file mode 100644
index 000000000..45a5e614c
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PutByIdStatus.h"
+
+#include "CodeBlock.h"
+#include "Structure.h"
+#include "StructureChain.h"
+
+namespace JSC {
+
+PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
+{
+ UNUSED_PARAM(profiledBlock);
+ UNUSED_PARAM(bytecodeIndex);
+ UNUSED_PARAM(ident);
+#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
+ if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
+ return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
+
+ StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex);
+ if (!stubInfo.seen)
+ return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
+
+ switch (stubInfo.accessType) {
+ case access_unset:
+ return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
+
+ case access_put_by_id_replace: {
+ size_t offset = stubInfo.u.putByIdReplace.baseObjectStructure->get(
+ *profiledBlock->globalData(), ident);
+ if (offset != notFound) {
+ return PutByIdStatus(
+ SimpleReplace,
+ stubInfo.u.putByIdReplace.baseObjectStructure.get(),
+ 0, 0,
+ offset);
+ }
+ return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
+ }
+
+ case access_put_by_id_transition_normal:
+ case access_put_by_id_transition_direct: {
+ size_t offset = stubInfo.u.putByIdTransition.structure->get(
+ *profiledBlock->globalData(), ident);
+ if (offset != notFound) {
+ return PutByIdStatus(
+ SimpleTransition,
+ stubInfo.u.putByIdTransition.previousStructure.get(),
+ stubInfo.u.putByIdTransition.structure.get(),
+ stubInfo.u.putByIdTransition.chain.get(),
+ offset);
+ }
+ return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
+ }
+
+ default:
+ return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound);
+ }
+#else // ENABLE(JIT)
+ return PutByIdStatus(NoInformation, 0, 0, 0, notFound);
+#endif // ENABLE(JIT)
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/bytecode/PutByIdStatus.h b/Source/JavaScriptCore/bytecode/PutByIdStatus.h
new file mode 100644
index 000000000..b33f4d09c
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/PutByIdStatus.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PutByIdStatus_h
+#define PutByIdStatus_h
+
+#include <wtf/NotFound.h>
+
+namespace JSC {
+
+class CodeBlock;
+class Identifier;
+class Structure;
+class StructureChain;
+
+class PutByIdStatus {
+public:
+ enum State {
+ // It's uncached so we have no information.
+ NoInformation,
+ // It's cached as a direct store into an object property for cases where the object
+ // already has the property.
+ SimpleReplace,
+ // It's cached as a transition from one structure that lacks the property to one that
+ // includes the property, and a direct store to this new property.
+ SimpleTransition,
+ // It's known to often take slow path.
+ TakesSlowPath
+ };
+
+ PutByIdStatus()
+ : m_state(NoInformation)
+ , m_oldStructure(0)
+ , m_newStructure(0)
+ , m_structureChain(0)
+ , m_offset(notFound)
+ {
+ }
+
+ PutByIdStatus(
+ State state,
+ Structure* oldStructure,
+ Structure* newStructure,
+ StructureChain* structureChain,
+ size_t offset)
+ : m_state(state)
+ , m_oldStructure(oldStructure)
+ , m_newStructure(newStructure)
+ , m_structureChain(structureChain)
+ , m_offset(offset)
+ {
+ ASSERT((m_state == NoInformation || m_state == TakesSlowPath) == !m_oldStructure);
+ ASSERT((m_state != SimpleTransition) == !m_newStructure);
+ ASSERT((m_state != SimpleTransition) == !m_structureChain);
+ ASSERT((m_state == NoInformation || m_state == TakesSlowPath) == (m_offset == notFound));
+ }
+
+ static PutByIdStatus computeFor(CodeBlock*, unsigned bytecodeIndex, Identifier&);
+
+ State state() const { return m_state; }
+
+ bool isSet() const { return m_state != NoInformation; }
+ bool operator!() const { return m_state == NoInformation; }
+ bool isSimpleReplace() const { return m_state == SimpleReplace; }
+ bool isSimpleTransition() const { return m_state == SimpleTransition; }
+ bool takesSlowPath() const { return m_state == TakesSlowPath; }
+
+ Structure* oldStructure() const { return m_oldStructure; }
+ Structure* newStructure() const { return m_newStructure; }
+ StructureChain* structureChain() const { return m_structureChain; }
+ size_t offset() const { return m_offset; }
+
+private:
+ State m_state;
+ Structure* m_oldStructure;
+ Structure* m_newStructure;
+ StructureChain* m_structureChain;
+ size_t m_offset;
+};
+
+} // namespace JSC
+
+#endif // PutByIdStatus_h
+
diff --git a/Source/JavaScriptCore/bytecode/SamplingTool.h b/Source/JavaScriptCore/bytecode/SamplingTool.h
index b69ef026e..32a44ad69 100644
--- a/Source/JavaScriptCore/bytecode/SamplingTool.h
+++ b/Source/JavaScriptCore/bytecode/SamplingTool.h
@@ -45,8 +45,8 @@ namespace JSC {
class SamplingFlags {
public:
- static void start();
- static void stop();
+ JS_EXPORT_PRIVATE static void start();
+ JS_EXPORT_PRIVATE static void stop();
#if ENABLE(SAMPLING_FLAGS)
static void setFlag(unsigned flag)
@@ -89,7 +89,7 @@ namespace JSC {
#endif
private:
- static uint32_t s_flags;
+ JS_EXPORTDATA static uint32_t s_flags;
#if ENABLE(SAMPLING_FLAGS)
static uint64_t s_flagCounts[33];
#endif
@@ -174,7 +174,7 @@ namespace JSC {
class SamplingRegion {
public:
SamplingRegion(const char*) { }
- void dump();
+ JS_EXPORT_PRIVATE void dump();
};
#endif // ENABLE(SAMPLING_REGIONS)
@@ -220,8 +220,8 @@ namespace JSC {
static unsigned s_hertz;
static ThreadIdentifier s_samplingThread;
- static void start(unsigned hertz=10000);
- static void stop();
+ JS_EXPORT_PRIVATE static void start(unsigned hertz=10000);
+ JS_EXPORT_PRIVATE static void stop();
static void* threadStartFunc(void*);
};
@@ -294,7 +294,7 @@ namespace JSC {
memset(m_opcodeSamplesInCTIFunctions, 0, sizeof(m_opcodeSamplesInCTIFunctions));
}
- void setup();
+ JS_EXPORT_PRIVATE void setup();
void dump(ExecState*);
void notifyOfScope(JSGlobalData&, ScriptExecutable* scope);
diff --git a/Source/JavaScriptCore/bytecode/StructureSet.h b/Source/JavaScriptCore/bytecode/StructureSet.h
new file mode 100644
index 000000000..344183b45
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/StructureSet.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StructureSet_h
+#define StructureSet_h
+
+#include "PredictedType.h"
+#include <stdio.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class Structure;
+
+namespace DFG {
+class StructureAbstractValue;
+}
+
+class StructureSet {
+public:
+ StructureSet() { }
+
+ StructureSet(Structure* structure)
+ {
+ m_structures.append(structure);
+ }
+
+ void clear()
+ {
+ m_structures.clear();
+ }
+
+ void add(Structure* structure)
+ {
+ ASSERT(!contains(structure));
+ m_structures.append(structure);
+ }
+
+ bool addAll(const StructureSet& other)
+ {
+ bool changed = false;
+ for (size_t i = 0; i < other.size(); ++i) {
+ if (contains(other[i]))
+ continue;
+ add(other[i]);
+ changed = true;
+ }
+ return changed;
+ }
+
+ void remove(Structure* structure)
+ {
+ for (size_t i = 0; i < m_structures.size(); ++i) {
+ if (m_structures[i] != structure)
+ continue;
+
+ m_structures[i] = m_structures.last();
+ m_structures.removeLast();
+ return;
+ }
+ }
+
+ bool contains(Structure* structure) const
+ {
+ for (size_t i = 0; i < m_structures.size(); ++i) {
+ if (m_structures[i] == structure)
+ return true;
+ }
+ return false;
+ }
+
+ bool isSubsetOf(const StructureSet& other) const
+ {
+ for (size_t i = 0; i < m_structures.size(); ++i) {
+ if (!other.contains(m_structures[i]))
+ return false;
+ }
+ return true;
+ }
+
+ bool isSupersetOf(const StructureSet& other) const
+ {
+ return other.isSubsetOf(*this);
+ }
+
+ size_t size() const { return m_structures.size(); }
+
+ Structure* at(size_t i) const { return m_structures.at(i); }
+
+ Structure* operator[](size_t i) const { return at(i); }
+
+ Structure* last() const { return m_structures.last(); }
+
+ PredictedType predictionFromStructures() const
+ {
+ PredictedType result = PredictNone;
+
+ for (size_t i = 0; i < m_structures.size(); ++i)
+ mergePrediction(result, predictionFromStructure(m_structures[i]));
+
+ return result;
+ }
+
+ bool operator==(const StructureSet& other) const
+ {
+ if (m_structures.size() != other.m_structures.size())
+ return false;
+
+ for (size_t i = 0; i < m_structures.size(); ++i) {
+ if (!other.contains(m_structures[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ void dump(FILE* out)
+ {
+ fprintf(out, "[");
+ for (size_t i = 0; i < m_structures.size(); ++i) {
+ if (i)
+ fprintf(out, ", ");
+ fprintf(out, "%p", m_structures[i]);
+ }
+ fprintf(out, "]");
+ }
+
+private:
+ friend class DFG::StructureAbstractValue;
+
+ Vector<Structure*, 2> m_structures;
+};
+
+} // namespace JSC
+
+#endif // StructureSet_h
diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.h b/Source/JavaScriptCore/bytecode/StructureStubInfo.h
index 5c7ee0bb8..d6b6092d0 100644
--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.h
+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.h
@@ -28,6 +28,7 @@
#if ENABLE(JIT)
+#include "CodeOrigin.h"
#include "Instruction.h"
#include "MacroAssembler.h"
#include "Opcode.h"
@@ -175,6 +176,8 @@ namespace JSC {
int8_t seen;
#if ENABLE(DFG_JIT)
+ CodeOrigin codeOrigin;
+ int8_t registersFlushed;
int8_t baseGPR;
#if USE(JSVALUE32_64)
int8_t valueTagGPR;