summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/javascriptcore/JavaScriptCore/bytecode
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-09-24 14:35:49 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-09-24 15:36:17 (GMT)
commitaabd12223bda6260756ab19430082477d5669c0a (patch)
tree6ca7a12e627915992cfd0038f6ddd8ee244711f4 /src/3rdparty/javascriptcore/JavaScriptCore/bytecode
parent270c374c178ec5a532d37168b018cd7ebc844558 (diff)
downloadQt-aabd12223bda6260756ab19430082477d5669c0a.zip
Qt-aabd12223bda6260756ab19430082477d5669c0a.tar.gz
Qt-aabd12223bda6260756ab19430082477d5669c0a.tar.bz2
Update src/3rdparty/javascriptcore and adapt src/script to the changes.
Reviewed-by: Simon Hausmann
Diffstat (limited to 'src/3rdparty/javascriptcore/JavaScriptCore/bytecode')
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp182
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h152
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h36
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Instruction.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h3
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.cpp28
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.h49
9 files changed, 218 insertions, 238 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp
index 596d89a..7e5f6cf 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -33,6 +33,8 @@
#include "JIT.h"
#include "JSValue.h"
#include "Interpreter.h"
+#include "JSFunction.h"
+#include "JSStaticScopeObject.h"
#include "Debugger.h"
#include "BytecodeGenerator.h"
#include <stdio.h>
@@ -57,6 +59,9 @@ static UString escapeQuotes(const UString& str)
static UString valueToSourceString(ExecState* exec, JSValue val)
{
+ if (!val)
+ return "0";
+
if (val.isString()) {
UString result("\"");
result += escapeQuotes(val.toString(exec)) + "\"";
@@ -227,44 +232,44 @@ static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigne
static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset)
{
- switch (stubInfo.opcodeID) {
- case op_get_by_id_self:
+ switch (stubInfo.accessType) {
+ case access_get_by_id_self:
printf(" [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).UTF8String().c_str());
return;
- case op_get_by_id_proto:
+ case access_get_by_id_proto:
printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).UTF8String().c_str());
return;
- case op_get_by_id_chain:
+ case access_get_by_id_chain:
printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdChain.chain).UTF8String().c_str());
return;
- case op_get_by_id_self_list:
+ case access_get_by_id_self_list:
printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).UTF8String().c_str(), stubInfo.u.getByIdSelfList.listSize);
return;
- case op_get_by_id_proto_list:
+ case access_get_by_id_proto_list:
printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).UTF8String().c_str(), stubInfo.u.getByIdProtoList.listSize);
return;
- case op_put_by_id_transition:
+ case access_put_by_id_transition:
printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).UTF8String().c_str());
return;
- case op_put_by_id_replace:
+ case access_put_by_id_replace:
printf(" [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).UTF8String().c_str());
return;
- case op_get_by_id:
+ case access_get_by_id:
printf(" [%4d] %s\n", instructionOffset, "get_by_id");
return;
- case op_put_by_id:
+ case access_put_by_id:
printf(" [%4d] %s\n", instructionOffset, "put_by_id");
return;
- case op_get_by_id_generic:
+ case access_get_by_id_generic:
printf(" [%4d] %s\n", instructionOffset, "op_get_by_id_generic");
return;
- case op_put_by_id_generic:
+ case access_put_by_id_generic:
printf(" [%4d] %s\n", instructionOffset, "op_put_by_id_generic");
return;
- case op_get_array_length:
+ case access_get_array_length:
printf(" [%4d] %s\n", instructionOffset, "op_get_array_length");
return;
- case op_get_string_length:
+ case access_get_string_length:
printf(" [%4d] %s\n", instructionOffset, "op_get_string_length");
return;
default:
@@ -595,6 +600,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
case op_div: {
printBinaryOp(location, it, "div");
+ ++it;
break;
}
case op_mod: {
@@ -739,13 +745,6 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
break;
}
- case op_resolve_func: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int id0 = (++it)->u.operand;
- printf("[%4d] resolve_func\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
- break;
- }
case op_get_by_id: {
printGetByIdOp(location, it, m_identifiers, "get_by_id");
break;
@@ -1250,45 +1249,23 @@ void CodeBlock::dumpStatistics()
#endif
}
-CodeBlock::CodeBlock(ScopeNode* ownerNode)
- : m_numCalleeRegisters(0)
- , m_numVars(0)
- , m_numParameters(0)
- , m_ownerNode(ownerNode)
- , m_globalData(0)
-#ifndef NDEBUG
- , m_instructionCount(0)
-#endif
- , m_needsFullScopeChain(false)
- , m_usesEval(false)
- , m_usesArguments(false)
- , m_isNumericCompareFunction(false)
- , m_codeType(NativeCode)
- , m_source(0)
- , m_sourceOffset(0)
- , m_exceptionInfo(0)
-{
-#if DUMP_CODE_BLOCK_STATISTICS
- liveCodeBlockSet.add(this);
-#endif
-}
-
-CodeBlock::CodeBlock(ScopeNode* ownerNode, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset)
+CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, SymbolTable* symTab)
: m_numCalleeRegisters(0)
, m_numVars(0)
, m_numParameters(0)
- , m_ownerNode(ownerNode)
+ , m_ownerExecutable(ownerExecutable)
, m_globalData(0)
#ifndef NDEBUG
, m_instructionCount(0)
#endif
- , m_needsFullScopeChain(ownerNode->needsActivation())
- , m_usesEval(ownerNode->usesEval())
- , m_usesArguments(ownerNode->usesArguments())
+ , m_needsFullScopeChain(ownerExecutable->needsActivation())
+ , m_usesEval(ownerExecutable->usesEval())
+ , m_usesArguments(ownerExecutable->usesArguments())
, m_isNumericCompareFunction(false)
, m_codeType(codeType)
, m_source(sourceProvider)
, m_sourceOffset(sourceOffset)
+ , m_symbolTable(symTab)
, m_exceptionInfo(new ExceptionInfo)
{
ASSERT(m_source);
@@ -1325,20 +1302,23 @@ CodeBlock::~CodeBlock()
if (Structure* structure = m_methodCallLinkInfos[i].cachedStructure) {
structure->deref();
// Both members must be filled at the same time
- ASSERT(m_methodCallLinkInfos[i].cachedPrototypeStructure);
+ ASSERT(!!m_methodCallLinkInfos[i].cachedPrototypeStructure);
m_methodCallLinkInfos[i].cachedPrototypeStructure->deref();
}
}
+#if ENABLE(JIT_OPTIMIZE_CALL)
unlinkCallers();
#endif
+#endif // !ENABLE(JIT)
+
#if DUMP_CODE_BLOCK_STATISTICS
liveCodeBlockSet.remove(this);
#endif
}
-#if ENABLE(JIT)
+#if ENABLE(JIT_OPTIMIZE_CALL)
void CodeBlock::unlinkCallers()
{
size_t size = m_linkedCallerList.size();
@@ -1353,7 +1333,6 @@ void CodeBlock::unlinkCallers()
void CodeBlock::derefStructures(Instruction* vPC) const
{
- ASSERT(m_codeType != NativeCode);
Interpreter* interpreter = m_globalData->interpreter;
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
@@ -1399,7 +1378,6 @@ void CodeBlock::derefStructures(Instruction* vPC) const
void CodeBlock::refStructures(Instruction* vPC) const
{
- ASSERT(m_codeType != NativeCode);
Interpreter* interpreter = m_globalData->interpreter;
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
@@ -1431,26 +1409,18 @@ void CodeBlock::refStructures(Instruction* vPC) const
ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic));
}
-void CodeBlock::mark()
+void CodeBlock::markAggregate(MarkStack& markStack)
{
for (size_t i = 0; i < m_constantRegisters.size(); ++i)
- if (!m_constantRegisters[i].marked())
- m_constantRegisters[i].mark();
-
- for (size_t i = 0; i < m_functionExpressions.size(); ++i)
- m_functionExpressions[i]->body()->mark();
-
- if (m_rareData) {
- for (size_t i = 0; i < m_rareData->m_functions.size(); ++i)
- m_rareData->m_functions[i]->body()->mark();
-
- m_rareData->m_evalCodeCache.mark();
- }
+ markStack.append(m_constantRegisters[i].jsValue());
+ for (size_t i = 0; i < m_functionExprs.size(); ++i)
+ m_functionExprs[i]->markAggregate(markStack);
+ for (size_t i = 0; i < m_functionDecls.size(); ++i)
+ m_functionDecls[i]->markAggregate(markStack);
}
void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
{
- ASSERT(m_codeType != NativeCode);
if (m_exceptionInfo)
return;
@@ -1467,61 +1437,11 @@ void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
scopeChain = scopeChain->next;
}
- switch (m_codeType) {
- case FunctionCode: {
- FunctionBodyNode* ownerFunctionBodyNode = static_cast<FunctionBodyNode*>(m_ownerNode);
- RefPtr<FunctionBodyNode> newFunctionBody = m_globalData->parser->reparse<FunctionBodyNode>(m_globalData, ownerFunctionBodyNode);
- ASSERT(newFunctionBody);
- newFunctionBody->finishParsing(ownerFunctionBodyNode->copyParameters(), ownerFunctionBodyNode->parameterCount());
-
- m_globalData->scopeNodeBeingReparsed = newFunctionBody.get();
-
- CodeBlock& newCodeBlock = newFunctionBody->bytecodeForExceptionInfoReparse(scopeChain, this);
- ASSERT(newCodeBlock.m_exceptionInfo);
- ASSERT(newCodeBlock.m_instructionCount == m_instructionCount);
-
-#if ENABLE(JIT)
- JIT::compile(m_globalData, &newCodeBlock);
- ASSERT(newFunctionBody->generatedJITCode().size() == ownerNode()->generatedJITCode().size());
-#endif
-
- m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release());
-
- m_globalData->scopeNodeBeingReparsed = 0;
-
- break;
- }
- case EvalCode: {
- EvalNode* ownerEvalNode = static_cast<EvalNode*>(m_ownerNode);
- RefPtr<EvalNode> newEvalBody = m_globalData->parser->reparse<EvalNode>(m_globalData, ownerEvalNode);
-
- m_globalData->scopeNodeBeingReparsed = newEvalBody.get();
-
- EvalCodeBlock& newCodeBlock = newEvalBody->bytecodeForExceptionInfoReparse(scopeChain, this);
- ASSERT(newCodeBlock.m_exceptionInfo);
- ASSERT(newCodeBlock.m_instructionCount == m_instructionCount);
-
-#if ENABLE(JIT)
- JIT::compile(m_globalData, &newCodeBlock);
- ASSERT(newEvalBody->generatedJITCode().size() == ownerNode()->generatedJITCode().size());
-#endif
-
- m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release());
-
- m_globalData->scopeNodeBeingReparsed = 0;
-
- break;
- }
- default:
- // CodeBlocks for Global code blocks are transient and therefore to not gain from
- // from throwing out there exception information.
- ASSERT_NOT_REACHED();
- }
+ m_exceptionInfo.set(m_ownerExecutable->reparseExceptionInfo(m_globalData, scopeChain, this));
}
HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
{
- ASSERT(m_codeType != NativeCode);
ASSERT(bytecodeOffset < m_instructionCount);
if (!m_rareData)
@@ -1540,14 +1460,13 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset)
{
- ASSERT(m_codeType != NativeCode);
ASSERT(bytecodeOffset < m_instructionCount);
reparseForExceptionInfoIfNecessary(callFrame);
ASSERT(m_exceptionInfo);
if (!m_exceptionInfo->m_lineInfo.size())
- return m_ownerNode->source().firstLine(); // Empty function
+ return m_ownerExecutable->source().firstLine(); // Empty function
int low = 0;
int high = m_exceptionInfo->m_lineInfo.size();
@@ -1560,13 +1479,12 @@ int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned byteco
}
if (!low)
- return m_ownerNode->source().firstLine();
+ return m_ownerExecutable->source().firstLine();
return m_exceptionInfo->m_lineInfo[low - 1].lineNumber;
}
int CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
{
- ASSERT(m_codeType != NativeCode);
ASSERT(bytecodeOffset < m_instructionCount);
reparseForExceptionInfoIfNecessary(callFrame);
@@ -1606,7 +1524,6 @@ int CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned b
bool CodeBlock::getByIdExceptionInfoForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, OpcodeID& opcodeID)
{
- ASSERT(m_codeType != NativeCode);
ASSERT(bytecodeOffset < m_instructionCount);
reparseForExceptionInfoIfNecessary(callFrame);
@@ -1635,7 +1552,6 @@ bool CodeBlock::getByIdExceptionInfoForBytecodeOffset(CallFrame* callFrame, unsi
#if ENABLE(JIT)
bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex)
{
- ASSERT(m_codeType != NativeCode);
ASSERT(bytecodeOffset < m_instructionCount);
if (!m_rareData || !m_rareData->m_functionRegisterInfos.size())
@@ -1662,7 +1578,6 @@ bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int&
#if !ENABLE(JIT)
bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset)
{
- ASSERT(m_codeType != NativeCode);
if (m_globalResolveInstructions.isEmpty())
return false;
@@ -1683,7 +1598,6 @@ bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOff
#else
bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
{
- ASSERT(m_codeType != NativeCode);
if (m_globalResolveInfos.isEmpty())
return false;
@@ -1703,18 +1617,6 @@ bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
}
#endif
-#if ENABLE(JIT)
-void CodeBlock::setJITCode(JITCode jitCode)
-{
- ASSERT(m_codeType != NativeCode);
- ownerNode()->setJITCode(jitCode);
-#if !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- m_instructions.clear();
-#endif
-}
-#endif
-
void CodeBlock::shrinkToFit()
{
m_instructions.shrinkToFit();
@@ -1730,7 +1632,8 @@ void CodeBlock::shrinkToFit()
#endif
m_identifiers.shrinkToFit();
- m_functionExpressions.shrinkToFit();
+ m_functionDecls.shrinkToFit();
+ m_functionExprs.shrinkToFit();
m_constantRegisters.shrinkToFit();
if (m_exceptionInfo) {
@@ -1741,7 +1644,6 @@ void CodeBlock::shrinkToFit()
if (m_rareData) {
m_rareData->m_exceptionHandlers.shrinkToFit();
- m_rareData->m_functions.shrinkToFit();
m_rareData->m_regexps.shrinkToFit();
m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
m_rareData->m_characterSwitchJumpTables.shrinkToFit();
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h
index e9f2697..0163540 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h
@@ -36,6 +36,7 @@
#include "JSGlobalObject.h"
#include "JumpTable.h"
#include "Nodes.h"
+#include "PtrAndFlags.h"
#include "RegExp.h"
#include "UString.h"
#include <wtf/FastAllocBase.h>
@@ -54,9 +55,13 @@ static const int FirstConstantRegisterIndex = 0x40000000;
namespace JSC {
+ enum HasSeenShouldRepatch {
+ hasSeenShouldRepatch
+ };
+
class ExecState;
- enum CodeType { GlobalCode, EvalCode, FunctionCode, NativeCode };
+ enum CodeType { GlobalCode, EvalCode, FunctionCode };
static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); }
@@ -105,25 +110,44 @@ namespace JSC {
CodeLocationNearCall callReturnLocation;
CodeLocationDataLabelPtr hotPathBegin;
CodeLocationNearCall hotPathOther;
- CodeBlock* ownerCodeBlock;
+ PtrAndFlags<CodeBlock, HasSeenShouldRepatch> ownerCodeBlock;
CodeBlock* callee;
unsigned position;
void setUnlinked() { callee = 0; }
bool isLinked() { return callee; }
+
+ bool seenOnce()
+ {
+ return ownerCodeBlock.isFlagSet(hasSeenShouldRepatch);
+ }
+
+ void setSeen()
+ {
+ ownerCodeBlock.setFlag(hasSeenShouldRepatch);
+ }
};
struct MethodCallLinkInfo {
MethodCallLinkInfo()
: cachedStructure(0)
- , cachedPrototypeStructure(0)
{
}
+ bool seenOnce()
+ {
+ return cachedPrototypeStructure.isFlagSet(hasSeenShouldRepatch);
+ }
+
+ void setSeen()
+ {
+ cachedPrototypeStructure.setFlag(hasSeenShouldRepatch);
+ }
+
CodeLocationCall callReturnLocation;
CodeLocationDataLabelPtr structureLabel;
Structure* cachedStructure;
- Structure* cachedPrototypeStructure;
+ PtrAndFlags<Structure, HasSeenShouldRepatch> cachedPrototypeStructure;
};
struct FunctionRegisterInfo {
@@ -224,17 +248,27 @@ namespace JSC {
}
#endif
+ struct ExceptionInfo : FastAllocBase {
+ Vector<ExpressionRangeInfo> m_expressionInfo;
+ Vector<LineInfo> m_lineInfo;
+ Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo;
+
+#if ENABLE(JIT)
+ Vector<CallReturnOffsetToBytecodeIndex> m_callReturnIndexVector;
+#endif
+ };
+
class CodeBlock : public FastAllocBase {
friend class JIT;
+ protected:
+ CodeBlock(ScriptExecutable* ownerExecutable, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset, SymbolTable* symbolTable);
public:
- CodeBlock(ScopeNode* ownerNode);
- CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset);
- ~CodeBlock();
+ virtual ~CodeBlock();
- void mark();
+ void markAggregate(MarkStack&);
void refStructures(Instruction* vPC) const;
void derefStructures(Instruction* vPC) const;
-#if ENABLE(JIT)
+#if ENABLE(JIT_OPTIMIZE_CALL)
void unlinkCallers();
#endif
@@ -305,7 +339,7 @@ namespace JSC {
unsigned getBytecodeIndex(CallFrame* callFrame, ReturnAddressPtr returnAddress)
{
reparseForExceptionInfoIfNecessary(callFrame);
- return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(m_exceptionInfo->m_callReturnIndexVector.begin(), m_exceptionInfo->m_callReturnIndexVector.size(), ownerNode()->generatedJITCode().offsetOf(returnAddress.value()))->bytecodeIndex;
+ return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(callReturnIndexVector().begin(), callReturnIndexVector().size(), ownerExecutable()->generatedJITCode().offsetOf(returnAddress.value()))->bytecodeIndex;
}
bool functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex);
@@ -315,17 +349,19 @@ namespace JSC {
bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
Vector<Instruction>& instructions() { return m_instructions; }
+ void discardBytecode() { m_instructions.clear(); }
+
#ifndef NDEBUG
+ unsigned instructionCount() { return m_instructionCount; }
void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; }
#endif
#if ENABLE(JIT)
- JITCode& getJITCode() { return ownerNode()->generatedJITCode(); }
- void setJITCode(JITCode);
- ExecutablePool* executablePool() { return ownerNode()->getExecutablePool(); }
+ JITCode& getJITCode() { return ownerExecutable()->generatedJITCode(); }
+ ExecutablePool* executablePool() { return ownerExecutable()->getExecutablePool(); }
#endif
- ScopeNode* ownerNode() const { return m_ownerNode; }
+ ScriptExecutable* ownerExecutable() const { return m_ownerExecutable; }
void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; }
@@ -341,8 +377,8 @@ namespace JSC {
CodeType codeType() const { return m_codeType; }
- SourceProvider* source() const { ASSERT(m_codeType != NativeCode); return m_source.get(); }
- unsigned sourceOffset() const { ASSERT(m_codeType != NativeCode); return m_sourceOffset; }
+ SourceProvider* source() const { return m_source.get(); }
+ unsigned sourceOffset() const { return m_sourceOffset; }
size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
@@ -380,6 +416,7 @@ namespace JSC {
bool hasExceptionInfo() const { return m_exceptionInfo; }
void clearExceptionInfo() { m_exceptionInfo.clear(); }
+ ExceptionInfo* extractExceptionInfo() { ASSERT(m_exceptionInfo); return m_exceptionInfo.release(); }
void addExpressionInfo(const ExpressionRangeInfo& expressionInfo) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_expressionInfo.append(expressionInfo); }
void addGetByIdExceptionInfo(const GetByIdExceptionInfo& info) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_getByIdExceptionInfo.append(info); }
@@ -404,13 +441,11 @@ namespace JSC {
ALWAYS_INLINE bool isConstantRegisterIndex(int index) { return index >= FirstConstantRegisterIndex; }
ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].jsValue(); }
- unsigned addFunctionExpression(FuncExprNode* n) { unsigned size = m_functionExpressions.size(); m_functionExpressions.append(n); return size; }
- FuncExprNode* functionExpression(int index) const { return m_functionExpressions[index].get(); }
-
- unsigned addFunction(FuncDeclNode* n) { createRareDataIfNecessary(); unsigned size = m_rareData->m_functions.size(); m_rareData->m_functions.append(n); return size; }
- FuncDeclNode* function(int index) const { ASSERT(m_rareData); return m_rareData->m_functions[index].get(); }
-
- bool hasFunctions() const { return m_functionExpressions.size() || (m_rareData && m_rareData->m_functions.size()); }
+ unsigned addFunctionDecl(PassRefPtr<FunctionExecutable> n) { unsigned size = m_functionDecls.size(); m_functionDecls.append(n); return size; }
+ FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
+ int numberOfFunctionDecls() { return m_functionDecls.size(); }
+ unsigned addFunctionExpr(PassRefPtr<FunctionExecutable> n) { unsigned size = m_functionExprs.size(); m_functionExprs.append(n); return size; }
+ FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
@@ -431,9 +466,10 @@ namespace JSC {
StringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
- SymbolTable& symbolTable() { return m_symbolTable; }
+ SymbolTable* symbolTable() { return m_symbolTable; }
+ SharedSymbolTable* sharedSymbolTable() { ASSERT(m_codeType == FunctionCode); return static_cast<SharedSymbolTable*>(m_symbolTable); }
- EvalCodeCache& evalCodeCache() { ASSERT(m_codeType != NativeCode); createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
+ EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
void shrinkToFit();
@@ -452,12 +488,11 @@ namespace JSC {
void createRareDataIfNecessary()
{
- ASSERT(m_codeType != NativeCode);
if (!m_rareData)
m_rareData.set(new RareData);
}
- ScopeNode* m_ownerNode;
+ ScriptExecutable* m_ownerExecutable;
JSGlobalData* m_globalData;
Vector<Instruction> m_instructions;
@@ -493,26 +528,17 @@ namespace JSC {
// Constant Pool
Vector<Identifier> m_identifiers;
Vector<Register> m_constantRegisters;
- Vector<RefPtr<FuncExprNode> > m_functionExpressions;
-
- SymbolTable m_symbolTable;
+ Vector<RefPtr<FunctionExecutable> > m_functionDecls;
+ Vector<RefPtr<FunctionExecutable> > m_functionExprs;
- struct ExceptionInfo : FastAllocBase {
- Vector<ExpressionRangeInfo> m_expressionInfo;
- Vector<LineInfo> m_lineInfo;
- Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo;
+ SymbolTable* m_symbolTable;
-#if ENABLE(JIT)
- Vector<CallReturnOffsetToBytecodeIndex> m_callReturnIndexVector;
-#endif
- };
OwnPtr<ExceptionInfo> m_exceptionInfo;
struct RareData : FastAllocBase {
Vector<HandlerInfo> m_exceptionHandlers;
// Rare Constants
- Vector<RefPtr<FuncDeclNode> > m_functions;
Vector<RefPtr<RegExp> > m_regexps;
// Jump Tables
@@ -532,16 +558,16 @@ namespace JSC {
// Program code is not marked by any function, so we make the global object
// responsible for marking it.
- class ProgramCodeBlock : public CodeBlock {
+ class GlobalCodeBlock : public CodeBlock {
public:
- ProgramCodeBlock(ScopeNode* ownerNode, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider)
- : CodeBlock(ownerNode, codeType, sourceProvider, 0)
+ GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, JSGlobalObject* globalObject)
+ : CodeBlock(ownerExecutable, codeType, sourceProvider, sourceOffset, &m_unsharedSymbolTable)
, m_globalObject(globalObject)
{
m_globalObject->codeBlocks().add(this);
}
- ~ProgramCodeBlock()
+ ~GlobalCodeBlock()
{
if (m_globalObject)
m_globalObject->codeBlocks().remove(this);
@@ -551,20 +577,54 @@ namespace JSC {
private:
JSGlobalObject* m_globalObject; // For program and eval nodes, the global object that marks the constant pool.
+ SymbolTable m_unsharedSymbolTable;
+ };
+
+ class ProgramCodeBlock : public GlobalCodeBlock {
+ public:
+ ProgramCodeBlock(ProgramExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider)
+ : GlobalCodeBlock(ownerExecutable, codeType, sourceProvider, 0, globalObject)
+ {
+ }
};
- class EvalCodeBlock : public ProgramCodeBlock {
+ class EvalCodeBlock : public GlobalCodeBlock {
public:
- EvalCodeBlock(ScopeNode* ownerNode, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth)
- : ProgramCodeBlock(ownerNode, EvalCode, globalObject, sourceProvider)
+ EvalCodeBlock(EvalExecutable* ownerExecutable, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth)
+ : GlobalCodeBlock(ownerExecutable, EvalCode, sourceProvider, 0, globalObject)
, m_baseScopeDepth(baseScopeDepth)
{
}
int baseScopeDepth() const { return m_baseScopeDepth; }
+ const Identifier& variable(unsigned index) { return m_variables[index]; }
+ unsigned numVariables() { return m_variables.size(); }
+ void adoptVariables(Vector<Identifier>& variables)
+ {
+ ASSERT(m_variables.isEmpty());
+ m_variables.swap(variables);
+ }
+
private:
int m_baseScopeDepth;
+ Vector<Identifier> m_variables;
+ };
+
+ class FunctionCodeBlock : public CodeBlock {
+ public:
+ // Rather than using the usual RefCounted::create idiom for SharedSymbolTable we just use new
+ // as we need to initialise the CodeBlock before we could initialise any RefPtr to hold the shared
+ // symbol table, so we just pass as a raw pointer with a ref count of 1. We then manually deref
+ // in the destructor.
+ FunctionCodeBlock(FunctionExecutable* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset)
+ : CodeBlock(ownerExecutable, codeType, sourceProvider, sourceOffset, new SharedSymbolTable)
+ {
+ }
+ ~FunctionCodeBlock()
+ {
+ sharedSymbolTable()->deref();
+ }
};
inline Register& ExecState::r(int index)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h
index f0ce73e..0e1fb1e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/EvalCodeCache.h
@@ -29,6 +29,7 @@
#ifndef EvalCodeCache_h
#define EvalCodeCache_h
+#include "Executable.h"
#include "JSGlobalObject.h"
#include "Nodes.h"
#include "Parser.h"
@@ -41,44 +42,33 @@ namespace JSC {
class EvalCodeCache {
public:
- PassRefPtr<EvalNode> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
+ PassRefPtr<EvalExecutable> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
{
- RefPtr<EvalNode> evalNode;
+ RefPtr<EvalExecutable> evalExecutable;
if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())
- evalNode = m_cacheMap.get(evalSource.rep());
+ evalExecutable = m_cacheMap.get(evalSource.rep());
- if (!evalNode) {
- int errorLine;
- UString errorMessage;
-
- SourceCode source = makeSource(evalSource);
- evalNode = exec->globalData().parser->parse<EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errorLine, &errorMessage);
- if (evalNode) {
- if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
- m_cacheMap.set(evalSource.rep(), evalNode);
- } else {
- exceptionValue = Error::create(exec, SyntaxError, errorMessage, errorLine, source.provider()->asID(), 0);
+ if (!evalExecutable) {
+ evalExecutable = EvalExecutable::create(makeSource(evalSource));
+ exceptionValue = evalExecutable->compile(exec, scopeChain);
+ if (exceptionValue)
return 0;
- }
+
+ if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
+ m_cacheMap.set(evalSource.rep(), evalExecutable);
}
- return evalNode.release();
+ return evalExecutable.release();
}
bool isEmpty() const { return m_cacheMap.isEmpty(); }
- void mark()
- {
- EvalCacheMap::iterator end = m_cacheMap.end();
- for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr)
- ptr->second->mark();
- }
private:
static const int maxCacheableSourceLength = 256;
static const int maxCacheEntries = 64;
- typedef HashMap<RefPtr<UString::Rep>, RefPtr<EvalNode> > EvalCacheMap;
+ typedef HashMap<RefPtr<UString::Rep>, RefPtr<EvalExecutable> > EvalCacheMap;
EvalCacheMap m_cacheMap;
};
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Instruction.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Instruction.h
index 594c4dd..bc2de19 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Instruction.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Instruction.h
@@ -54,7 +54,7 @@ namespace JSC {
class StructureChain;
// Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream.
- struct PolymorphicAccessStructureList {
+ struct PolymorphicAccessStructureList : FastAllocBase {
struct PolymorphicStubInfo {
bool isChain;
PolymorphicAccessStructureListStubRoutineType stubRoutine;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h
index 4baa0be..cf50442 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h
@@ -67,7 +67,7 @@ namespace JSC {
macro(op_negate, 3) \
macro(op_add, 5) \
macro(op_mul, 5) \
- macro(op_div, 4) \
+ macro(op_div, 5) \
macro(op_mod, 4) \
macro(op_sub, 5) \
\
@@ -98,7 +98,6 @@ namespace JSC {
macro(op_put_global_var, 4) \
macro(op_resolve_base, 3) \
macro(op_resolve_with_base, 4) \
- macro(op_resolve_func, 4) \
macro(op_get_by_id, 8) \
macro(op_get_by_id_self, 8) \
macro(op_get_by_id_self_list, 8) \
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp
index 8651723..8d0faa1 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp
@@ -197,7 +197,7 @@ void SamplingTool::doRun()
#if ENABLE(CODEBLOCK_SAMPLING)
if (CodeBlock* codeBlock = sample.codeBlock()) {
MutexLocker locker(m_scopeSampleMapMutex);
- ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerNode());
+ ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerExecutable());
ASSERT(record);
record->sample(codeBlock, sample.vPC());
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h
index fa95603..1a3f7cf 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h
@@ -136,7 +136,7 @@ namespace JSC {
class SamplingTool {
public:
- friend class CallRecord;
+ friend struct CallRecord;
friend class HostCallRecord;
#if ENABLE(OPCODE_SAMPLING)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.cpp
index bf3fdc4..018d832 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.cpp
@@ -31,44 +31,44 @@ namespace JSC {
#if ENABLE(JIT)
void StructureStubInfo::deref()
{
- switch (opcodeID) {
- case op_get_by_id_self:
+ switch (accessType) {
+ case access_get_by_id_self:
u.getByIdSelf.baseObjectStructure->deref();
return;
- case op_get_by_id_proto:
+ case access_get_by_id_proto:
u.getByIdProto.baseObjectStructure->deref();
u.getByIdProto.prototypeStructure->deref();
return;
- case op_get_by_id_chain:
+ case access_get_by_id_chain:
u.getByIdChain.baseObjectStructure->deref();
u.getByIdChain.chain->deref();
return;
- case op_get_by_id_self_list: {
+ case access_get_by_id_self_list: {
PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
polymorphicStructures->derefStructures(u.getByIdSelfList.listSize);
delete polymorphicStructures;
return;
}
- case op_get_by_id_proto_list: {
+ case access_get_by_id_proto_list: {
PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList;
polymorphicStructures->derefStructures(u.getByIdProtoList.listSize);
delete polymorphicStructures;
return;
}
- case op_put_by_id_transition:
+ case access_put_by_id_transition:
u.putByIdTransition.previousStructure->deref();
u.putByIdTransition.structure->deref();
u.putByIdTransition.chain->deref();
return;
- case op_put_by_id_replace:
+ case access_put_by_id_replace:
u.putByIdReplace.baseObjectStructure->deref();
return;
- case op_get_by_id:
- case op_put_by_id:
- case op_get_by_id_generic:
- case op_put_by_id_generic:
- case op_get_array_length:
- case op_get_string_length:
+ case access_get_by_id:
+ case access_put_by_id:
+ case access_get_by_id_generic:
+ case access_put_by_id_generic:
+ case access_get_array_length:
+ case access_get_string_length:
// These instructions don't ref their Structures.
return;
default:
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.h
index 95dd266..8e2c489 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/StructureStubInfo.h
@@ -35,15 +35,32 @@
namespace JSC {
+ enum AccessType {
+ access_get_by_id_self,
+ access_get_by_id_proto,
+ access_get_by_id_chain,
+ access_get_by_id_self_list,
+ access_get_by_id_proto_list,
+ access_put_by_id_transition,
+ access_put_by_id_replace,
+ access_get_by_id,
+ access_put_by_id,
+ access_get_by_id_generic,
+ access_put_by_id_generic,
+ access_get_array_length,
+ access_get_string_length,
+ };
+
struct StructureStubInfo {
- StructureStubInfo(OpcodeID opcodeID)
- : opcodeID(opcodeID)
+ StructureStubInfo(AccessType accessType)
+ : accessType(accessType)
+ , seen(false)
{
}
void initGetByIdSelf(Structure* baseObjectStructure)
{
- opcodeID = op_get_by_id_self;
+ accessType = access_get_by_id_self;
u.getByIdSelf.baseObjectStructure = baseObjectStructure;
baseObjectStructure->ref();
@@ -51,7 +68,7 @@ namespace JSC {
void initGetByIdProto(Structure* baseObjectStructure, Structure* prototypeStructure)
{
- opcodeID = op_get_by_id_proto;
+ accessType = access_get_by_id_proto;
u.getByIdProto.baseObjectStructure = baseObjectStructure;
baseObjectStructure->ref();
@@ -62,7 +79,7 @@ namespace JSC {
void initGetByIdChain(Structure* baseObjectStructure, StructureChain* chain)
{
- opcodeID = op_get_by_id_chain;
+ accessType = access_get_by_id_chain;
u.getByIdChain.baseObjectStructure = baseObjectStructure;
baseObjectStructure->ref();
@@ -73,7 +90,7 @@ namespace JSC {
void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
{
- opcodeID = op_get_by_id_self_list;
+ accessType = access_get_by_id_self_list;
u.getByIdProtoList.structureList = structureList;
u.getByIdProtoList.listSize = listSize;
@@ -81,7 +98,7 @@ namespace JSC {
void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize)
{
- opcodeID = op_get_by_id_proto_list;
+ accessType = access_get_by_id_proto_list;
u.getByIdProtoList.structureList = structureList;
u.getByIdProtoList.listSize = listSize;
@@ -91,7 +108,7 @@ namespace JSC {
void initPutByIdTransition(Structure* previousStructure, Structure* structure, StructureChain* chain)
{
- opcodeID = op_put_by_id_transition;
+ accessType = access_put_by_id_transition;
u.putByIdTransition.previousStructure = previousStructure;
previousStructure->ref();
@@ -105,7 +122,7 @@ namespace JSC {
void initPutByIdReplace(Structure* baseObjectStructure)
{
- opcodeID = op_put_by_id_replace;
+ accessType = access_put_by_id_replace;
u.putByIdReplace.baseObjectStructure = baseObjectStructure;
baseObjectStructure->ref();
@@ -113,7 +130,19 @@ namespace JSC {
void deref();
- OpcodeID opcodeID;
+ bool seenOnce()
+ {
+ return seen;
+ }
+
+ void setSeen()
+ {
+ seen = true;
+ }
+
+ int accessType : 31;
+ int seen : 1;
+
union {
struct {
Structure* baseObjectStructure;