summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/JavaScriptCore/bytecode
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/bytecode')
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp241
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.h152
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/bytecode/EvalCodeCache.h36
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/bytecode/Instruction.h2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h8
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.cpp30
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.h24
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/bytecode/StructureStubInfo.cpp28
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/bytecode/StructureStubInfo.h49
9 files changed, 282 insertions, 288 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp b/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp
index 0cb381331..c9159341d 100644
--- a/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/src/3rdparty/webkit/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)) + "\"";
@@ -130,11 +135,6 @@ NEVER_INLINE static const char* debugHookName(int debugHookID)
return "";
}
-static int locationForOffset(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int offset)
-{
- return it - begin + offset;
-}
-
static void printUnaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op)
{
int r0 = (++it)->u.operand;
@@ -151,11 +151,11 @@ static void printBinaryOp(int location, Vector<Instruction>::const_iterator& it,
printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
}
-static void printConditionalJump(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int location, const char* op)
+static void printConditionalJump(const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator& it, int location, const char* op)
{
int r0 = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, location + offset);
}
static void printGetByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op)
@@ -227,44 +227,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 +595,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 +740,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;
@@ -830,6 +824,16 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
break;
}
+ case op_get_by_pname: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int r2 = (++it)->u.operand;
+ int r3 = (++it)->u.operand;
+ int r4 = (++it)->u.operand;
+ int r5 = (++it)->u.operand;
+ printf("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str(), registerName(r4).c_str(), registerName(r5).c_str());
+ break;
+ }
case op_put_by_val: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
@@ -853,12 +857,12 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
case op_jmp: {
int offset = (++it)->u.operand;
- printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset));
+ printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, location + offset);
break;
}
case op_loop: {
int offset = (++it)->u.operand;
- printf("[%4d] loop\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset));
+ printf("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset);
break;
}
case op_jtrue: {
@@ -885,56 +889,56 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset);
break;
}
case op_jnless: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset);
break;
}
case op_jnlesseq: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset);
break;
}
case op_loop_if_less: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset);
break;
}
case op_loop_if_lesseq: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, location + offset);
break;
}
case op_switch_imm: {
int tableIndex = (++it)->u.operand;
int defaultTarget = (++it)->u.operand;
int scrutineeRegister = (++it)->u.operand;
- printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
+ printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str());
break;
}
case op_switch_char: {
int tableIndex = (++it)->u.operand;
int defaultTarget = (++it)->u.operand;
int scrutineeRegister = (++it)->u.operand;
- printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
+ printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str());
break;
}
case op_switch_string: {
int tableIndex = (++it)->u.operand;
int defaultTarget = (++it)->u.operand;
int scrutineeRegister = (++it)->u.operand;
- printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
+ printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).c_str());
break;
}
case op_new_func: {
@@ -1021,16 +1025,21 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
break;
}
case op_get_pnames: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- printf("[%4d] get_pnames\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
+ int r0 = it[1].u.operand;
+ int r1 = it[2].u.operand;
+ int r2 = it[3].u.operand;
+ int r3 = it[4].u.operand;
+ int offset = it[5].u.operand;
+ printf("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str(), offset, location + offset);
+ it += OPCODE_LENGTH(op_get_pnames) - 1;
break;
}
case op_next_pname: {
- int dest = (++it)->u.operand;
- int iter = (++it)->u.operand;
- int offset = (++it)->u.operand;
- printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, locationForOffset(begin, it, offset));
+ int dest = it[1].u.operand;
+ int iter = it[4].u.operand;
+ int offset = it[5].u.operand;
+ printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, location + offset);
+ it += OPCODE_LENGTH(op_next_pname) - 1;
break;
}
case op_push_scope: {
@@ -1052,7 +1061,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
case op_jmp_scopes: {
int scopeDelta = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, locationForOffset(begin, it, offset));
+ printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, location + offset);
break;
}
case op_catch: {
@@ -1075,7 +1084,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
case op_jsr: {
int retAddrDst = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(retAddrDst).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(retAddrDst).c_str(), offset, location + offset);
break;
}
case op_sret: {
@@ -1249,43 +1258,22 @@ void CodeBlock::dumpStatistics()
#endif
}
-CodeBlock::CodeBlock(ScopeNode* ownerNode)
+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(false)
- , m_usesEval(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)
- : m_numCalleeRegisters(0)
- , m_numVars(0)
- , m_numParameters(0)
- , m_ownerNode(ownerNode)
- , m_globalData(0)
-#ifndef NDEBUG
- , m_instructionCount(0)
-#endif
- , m_needsFullScopeChain(ownerNode->needsActivation())
- , m_usesEval(ownerNode->usesEval())
+ , m_needsFullScopeChain(ownerExecutable->needsActivation())
+ , m_usesEval(ownerExecutable->usesEval())
, m_isNumericCompareFunction(false)
, m_codeType(codeType)
, m_source(sourceProvider)
, m_sourceOffset(sourceOffset)
+ , m_symbolTable(symTab)
, m_exceptionInfo(new ExceptionInfo)
{
ASSERT(m_source);
@@ -1322,20 +1310,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();
@@ -1350,7 +1341,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)) {
@@ -1396,7 +1386,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)) {
@@ -1428,26 +1417,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;
@@ -1464,61 +1445,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)
@@ -1537,14 +1468,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();
@@ -1557,13 +1487,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);
@@ -1603,7 +1532,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);
@@ -1632,7 +1560,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())
@@ -1659,7 +1586,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;
@@ -1680,7 +1606,6 @@ bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOff
#else
bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
{
- ASSERT(m_codeType != NativeCode);
if (m_globalResolveInfos.isEmpty())
return false;
@@ -1700,18 +1625,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();
@@ -1727,7 +1640,8 @@ void CodeBlock::shrinkToFit()
#endif
m_identifiers.shrinkToFit();
- m_functionExpressions.shrinkToFit();
+ m_functionDecls.shrinkToFit();
+ m_functionExprs.shrinkToFit();
m_constantRegisters.shrinkToFit();
if (m_exceptionInfo) {
@@ -1738,7 +1652,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/webkit/JavaScriptCore/bytecode/CodeBlock.h b/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.h
index e9f2697ec..4ba58d77e 100644
--- a/src/3rdparty/webkit/JavaScriptCore/bytecode/CodeBlock.h
+++ b/src/3rdparty/webkit/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(NonNullPassRefPtr<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(NonNullPassRefPtr<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/webkit/JavaScriptCore/bytecode/EvalCodeCache.h b/src/3rdparty/webkit/JavaScriptCore/bytecode/EvalCodeCache.h
index f0ce73e95..05834fcbf 100644
--- a/src/3rdparty/webkit/JavaScriptCore/bytecode/EvalCodeCache.h
+++ b/src/3rdparty/webkit/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(exec, 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/webkit/JavaScriptCore/bytecode/Instruction.h b/src/3rdparty/webkit/JavaScriptCore/bytecode/Instruction.h
index eeeac6f4c..bcef7fb19 100644
--- a/src/3rdparty/webkit/JavaScriptCore/bytecode/Instruction.h
+++ b/src/3rdparty/webkit/JavaScriptCore/bytecode/Instruction.h
@@ -53,7 +53,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/webkit/JavaScriptCore/bytecode/Opcode.h b/src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h
index 2d1ca981b..4facbef5b 100644
--- a/src/3rdparty/webkit/JavaScriptCore/bytecode/Opcode.h
+++ b/src/3rdparty/webkit/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) \
@@ -114,6 +113,7 @@ namespace JSC {
macro(op_put_by_id_generic, 8) \
macro(op_del_by_id, 4) \
macro(op_get_by_val, 4) \
+ macro(op_get_by_pname, 7) \
macro(op_put_by_val, 4) \
macro(op_del_by_val, 4) \
macro(op_put_by_index, 4) \
@@ -153,8 +153,8 @@ namespace JSC {
macro(op_strcat, 4) \
macro(op_to_primitive, 3) \
\
- macro(op_get_pnames, 3) \
- macro(op_next_pname, 4) \
+ macro(op_get_pnames, 6) \
+ macro(op_next_pname, 7) \
\
macro(op_push_scope, 2) \
macro(op_pop_scope, 1) \
diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.cpp b/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.cpp
index 86517233a..865c91933 100644
--- a/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.cpp
@@ -157,7 +157,7 @@ void SamplingThread::stop()
}
-void ScopeSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC)
+void ScriptSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC)
{
if (!m_samples) {
m_size = codeBlock->instructions().size();
@@ -196,8 +196,8 @@ void SamplingTool::doRun()
#if ENABLE(CODEBLOCK_SAMPLING)
if (CodeBlock* codeBlock = sample.codeBlock()) {
- MutexLocker locker(m_scopeSampleMapMutex);
- ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerNode());
+ MutexLocker locker(m_scriptSampleMapMutex);
+ ScriptSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerExecutable());
ASSERT(record);
record->sample(codeBlock, sample.vPC());
}
@@ -209,13 +209,13 @@ void SamplingTool::sample()
s_samplingTool->doRun();
}
-void SamplingTool::notifyOfScope(ScopeNode* scope)
+void SamplingTool::notifyOfScope(ScriptExecutable* script)
{
#if ENABLE(CODEBLOCK_SAMPLING)
- MutexLocker locker(m_scopeSampleMapMutex);
- m_scopeSampleMap->set(scope, new ScopeSampleRecord(scope));
+ MutexLocker locker(m_scriptSampleMapMutex);
+ m_scopeSampleMap->set(script, new ScriptSampleRecord(script));
#else
- UNUSED_PARAM(scope);
+ UNUSED_PARAM(script);
#endif
}
@@ -254,10 +254,10 @@ static int compareLineCountInfoSampling(const void* left, const void* right)
return (leftLineCount->line > rightLineCount->line) ? 1 : (leftLineCount->line < rightLineCount->line) ? -1 : 0;
}
-static int compareScopeSampleRecords(const void* left, const void* right)
+static int compareScriptSampleRecords(const void* left, const void* right)
{
- const ScopeSampleRecord* const leftValue = *static_cast<const ScopeSampleRecord* const *>(left);
- const ScopeSampleRecord* const rightValue = *static_cast<const ScopeSampleRecord* const *>(right);
+ const ScriptSampleRecord* const leftValue = *static_cast<const ScriptSampleRecord* const *>(left);
+ const ScriptSampleRecord* const rightValue = *static_cast<const ScriptSampleRecord* const *>(right);
return (leftValue->m_sampleCount < rightValue->m_sampleCount) ? 1 : (leftValue->m_sampleCount > rightValue->m_sampleCount) ? -1 : 0;
}
@@ -318,26 +318,26 @@ void SamplingTool::dump(ExecState* exec)
// (3) Build and sort 'codeBlockSamples' array.
int scopeCount = m_scopeSampleMap->size();
- Vector<ScopeSampleRecord*> codeBlockSamples(scopeCount);
- ScopeSampleRecordMap::iterator iter = m_scopeSampleMap->begin();
+ Vector<ScriptSampleRecord*> codeBlockSamples(scopeCount);
+ ScriptSampleRecordMap::iterator iter = m_scopeSampleMap->begin();
for (int i = 0; i < scopeCount; ++i, ++iter)
codeBlockSamples[i] = iter->second;
- qsort(codeBlockSamples.begin(), scopeCount, sizeof(ScopeSampleRecord*), compareScopeSampleRecords);
+ qsort(codeBlockSamples.begin(), scopeCount, sizeof(ScriptSampleRecord*), compareScriptSampleRecords);
// (4) Print data from 'codeBlockSamples' array.
printf("\nCodeBlock samples\n\n");
for (int i = 0; i < scopeCount; ++i) {
- ScopeSampleRecord* record = codeBlockSamples[i];
+ ScriptSampleRecord* record = codeBlockSamples[i];
CodeBlock* codeBlock = record->m_codeBlock;
double blockPercent = (record->m_sampleCount * 100.0) / m_sampleCount;
if (blockPercent >= 1) {
//Instruction* code = codeBlock->instructions().begin();
- printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_scope->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent);
+ printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent);
if (i < 10) {
HashMap<unsigned,unsigned> lineCounts;
codeBlock->dump(exec);
diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.h b/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.h
index fa95603a0..8e3ed9e5e 100644
--- a/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.h
+++ b/src/3rdparty/webkit/JavaScriptCore/bytecode/SamplingTool.h
@@ -38,6 +38,8 @@
namespace JSC {
+ class ScriptExecutable;
+
class SamplingFlags {
friend class JIT;
public:
@@ -92,9 +94,9 @@ namespace JSC {
class ScopeNode;
struct Instruction;
- struct ScopeSampleRecord {
- ScopeSampleRecord(ScopeNode* scope)
- : m_scope(scope)
+ struct ScriptSampleRecord {
+ ScriptSampleRecord(ScriptExecutable* executable)
+ : m_executable(executable)
, m_codeBlock(0)
, m_sampleCount(0)
, m_opcodeSampleCount(0)
@@ -103,7 +105,7 @@ namespace JSC {
{
}
- ~ScopeSampleRecord()
+ ~ScriptSampleRecord()
{
if (m_samples)
free(m_samples);
@@ -111,7 +113,7 @@ namespace JSC {
void sample(CodeBlock*, Instruction*);
- RefPtr<ScopeNode> m_scope;
+ RefPtr<ScriptExecutable> m_executable;
CodeBlock* m_codeBlock;
int m_sampleCount;
int m_opcodeSampleCount;
@@ -119,7 +121,7 @@ namespace JSC {
unsigned m_size;
};
- typedef WTF::HashMap<ScopeNode*, ScopeSampleRecord*> ScopeSampleRecordMap;
+ typedef WTF::HashMap<ScriptExecutable*, ScriptSampleRecord*> ScriptSampleRecordMap;
class SamplingThread {
public:
@@ -136,7 +138,7 @@ namespace JSC {
class SamplingTool {
public:
- friend class CallRecord;
+ friend struct CallRecord;
friend class HostCallRecord;
#if ENABLE(OPCODE_SAMPLING)
@@ -193,7 +195,7 @@ namespace JSC {
, m_sampleCount(0)
, m_opcodeSampleCount(0)
#if ENABLE(CODEBLOCK_SAMPLING)
- , m_scopeSampleMap(new ScopeSampleRecordMap())
+ , m_scopeSampleMap(new ScriptSampleRecordMap())
#endif
{
memset(m_opcodeSamples, 0, sizeof(m_opcodeSamples));
@@ -210,7 +212,7 @@ namespace JSC {
void setup();
void dump(ExecState*);
- void notifyOfScope(ScopeNode* scope);
+ void notifyOfScope(ScriptExecutable* scope);
void sample(CodeBlock* codeBlock, Instruction* vPC)
{
@@ -266,8 +268,8 @@ namespace JSC {
unsigned m_opcodeSamplesInCTIFunctions[numOpcodeIDs];
#if ENABLE(CODEBLOCK_SAMPLING)
- Mutex m_scopeSampleMapMutex;
- OwnPtr<ScopeSampleRecordMap> m_scopeSampleMap;
+ Mutex m_scriptSampleMapMutex;
+ OwnPtr<ScriptSampleRecordMap> m_scopeSampleMap;
#endif
};
diff --git a/src/3rdparty/webkit/JavaScriptCore/bytecode/StructureStubInfo.cpp b/src/3rdparty/webkit/JavaScriptCore/bytecode/StructureStubInfo.cpp
index bf3fdc465..018d83289 100644
--- a/src/3rdparty/webkit/JavaScriptCore/bytecode/StructureStubInfo.cpp
+++ b/src/3rdparty/webkit/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/webkit/JavaScriptCore/bytecode/StructureStubInfo.h b/src/3rdparty/webkit/JavaScriptCore/bytecode/StructureStubInfo.h
index 95dd2664a..8e2c489aa 100644
--- a/src/3rdparty/webkit/JavaScriptCore/bytecode/StructureStubInfo.h
+++ b/src/3rdparty/webkit/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;