diff options
Diffstat (limited to 'Source/JavaScriptCore/bytecode')
-rw-r--r-- | Source/JavaScriptCore/bytecode/CodeBlock.cpp | 130 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/CodeBlock.h | 52 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/DFGExitProfile.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/EvalCodeCache.h | 19 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/GetByIdStatus.cpp | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/GlobalResolveInfo.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/JumpTable.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/Opcode.h | 14 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/Operands.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/PutByIdStatus.cpp | 13 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/SpeculatedType.h | 10 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/StructureStubInfo.cpp | 2 |
13 files changed, 139 insertions, 117 deletions
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index 2ea969fcf..f15e5b0dd 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -40,12 +40,11 @@ #include "JITStubs.h" #include "JSActivation.h" #include "JSFunction.h" -#include "JSStaticScopeObject.h" +#include "JSNameScope.h" #include "JSValue.h" #include "LowLevelInterpreter.h" #include "MethodCallLinkStatus.h" #include "RepatchBuffer.h" -#include "UStringConcatenate.h" #include <stdio.h> #include <wtf/StringExtras.h> #include <wtf/UnusedParam.h> @@ -62,36 +61,36 @@ namespace JSC { using namespace DFG; #endif -static UString escapeQuotes(const UString& str) +static String escapeQuotes(const String& str) { - UString result = str; + String result = str; size_t pos = 0; while ((pos = result.find('\"', pos)) != notFound) { - result = makeUString(result.substringSharingImpl(0, pos), "\"\\\"\"", result.substringSharingImpl(pos + 1)); + result = makeString(result.substringSharingImpl(0, pos), "\"\\\"\"", result.substringSharingImpl(pos + 1)); pos += 4; } return result; } -static UString valueToSourceString(ExecState* exec, JSValue val) +static String valueToSourceString(ExecState* exec, JSValue val) { if (!val) - return "0"; + return ASCIILiteral("0"); if (val.isString()) - return makeUString("\"", escapeQuotes(val.toString(exec)->value(exec)), "\""); + return makeString("\"", escapeQuotes(val.toString(exec)->value(exec)), "\""); return val.description(); } static CString constantName(ExecState* exec, int k, JSValue value) { - return makeUString(valueToSourceString(exec, value), "(@k", UString::number(k - FirstConstantRegisterIndex), ")").utf8(); + return makeString(valueToSourceString(exec, value), "(@k", String::number(k - FirstConstantRegisterIndex), ")").utf8(); } static CString idName(int id0, const Identifier& ident) { - return makeUString(ident.ustring(), "(@id", UString::number(id0), ")").utf8(); + return makeString(ident.string(), "(@id", String::number(id0), ")").utf8(); } void CodeBlock::dumpBytecodeCommentAndNewLine(int location) @@ -114,10 +113,10 @@ CString CodeBlock::registerName(ExecState* exec, int r) const if (isConstantRegisterIndex(r)) return constantName(exec, r, getConstant(r)); - return makeUString("r", UString::number(r)).utf8(); + return makeString("r", String::number(r)).utf8(); } -static UString regexpToSourceString(RegExp* regExp) +static String regexpToSourceString(RegExp* regExp) { char postfix[5] = { '/', 0, 0, 0, 0 }; int index = 1; @@ -128,15 +127,15 @@ static UString regexpToSourceString(RegExp* regExp) if (regExp->multiline()) postfix[index] = 'm'; - return makeUString("/", regExp->pattern(), postfix); + return makeString("/", regExp->pattern(), postfix); } static CString regexpName(int re, RegExp* regexp) { - return makeUString(regexpToSourceString(regexp), "(@re", UString::number(re), ")").utf8(); + return makeString(regexpToSourceString(regexp), "(@re", String::number(re), ")").utf8(); } -static UString pointerToSourceString(void* p) +static String pointerToSourceString(void* p) { char buffer[2 + 2 * sizeof(void*) + 1]; // 0x [two characters per byte] \0 snprintf(buffer, sizeof(buffer), "%p", p); @@ -549,7 +548,7 @@ void CodeBlock::dump(ExecState* exec) dataLog("\nIdentifiers:\n"); size_t i = 0; do { - dataLog(" id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].ustring().utf8().data()); + dataLog(" id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].string().utf8().data()); ++i; } while (i != m_identifiers.size()); } @@ -642,7 +641,7 @@ void CodeBlock::dump(ExecState* exec) continue; ASSERT(!((i + m_rareData->m_characterSwitchJumpTables[i].min) & ~0xFFFF)); UChar ch = static_cast<UChar>(entry + m_rareData->m_characterSwitchJumpTables[i].min); - dataLog("\t\t\"%s\" => %04d\n", UString(&ch, 1).utf8().data(), *iter); + dataLog("\t\t\"%s\" => %04d\n", String(&ch, 1).utf8().data(), *iter); } dataLog(" }\n"); ++i; @@ -656,7 +655,7 @@ void CodeBlock::dump(ExecState* exec) dataLog(" %1d = {\n", i); StringJumpTable::StringOffsetTable::const_iterator end = m_rareData->m_stringSwitchJumpTables[i].offsetTable.end(); for (StringJumpTable::StringOffsetTable::const_iterator iter = m_rareData->m_stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter) - dataLog("\t\t\"%s\" => %04d\n", UString(iter->first).utf8().data(), iter->second.branchOffset); + dataLog("\t\t\"%s\" => %04d\n", String(iter->first).utf8().data(), iter->second.branchOffset); dataLog(" }\n"); ++i; } while (i < m_rareData->m_stringSwitchJumpTables.size()); @@ -1480,9 +1479,9 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& it += OPCODE_LENGTH(op_next_pname) - 1; break; } - case op_push_scope: { + case op_push_with_scope: { int r0 = (++it)->u.operand; - dataLog("[%4d] push_scope\t %s", location, registerName(exec, r0).data()); + dataLog("[%4d] push_with_scope\t %s", location, registerName(exec, r0).data()); dumpBytecodeCommentAndNewLine(location); break; } @@ -1491,11 +1490,11 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& dumpBytecodeCommentAndNewLine(location); break; } - case op_push_new_scope: { - int r0 = (++it)->u.operand; + case op_push_name_scope: { int id0 = (++it)->u.operand; int r1 = (++it)->u.operand; - dataLog("[%4d] push_new_scope \t%s, %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); + unsigned attributes = (++it)->u.operand; + dataLog("[%4d] push_name_scope \t%s, %s, %u", location, idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), attributes); dumpBytecodeCommentAndNewLine(location); break; } @@ -1551,6 +1550,10 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& dumpBytecodeCommentAndNewLine(location); break; } +#if ENABLE(LLINT_C_LOOP) + default: + ASSERT(false); // We should never get here. +#endif } } @@ -1678,7 +1681,7 @@ void CodeBlock::dumpStatistics() #endif } -CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab) +CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other) : m_globalObject(other.m_globalObject) , m_heap(other.m_heap) , m_numCalleeRegisters(other.m_numCalleeRegisters) @@ -1710,7 +1713,7 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab) , m_constantRegisters(other.m_constantRegisters) , m_functionDecls(other.m_functionDecls) , m_functionExprs(other.m_functionExprs) - , m_symbolTable(symTab) + , m_symbolTable(*other.m_globalData, other.m_ownerExecutable.get(), other.symbolTable()) , m_osrExitCounter(0) , m_optimizationDelayCounter(0) , m_reoptimizationRetryCounter(0) @@ -1744,11 +1747,12 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab) } } -CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, SymbolTable* symTab, bool isConstructor, PassOwnPtr<CodeBlock> alternative) +CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, bool isConstructor, PassOwnPtr<CodeBlock> alternative) : m_globalObject(globalObject->globalData(), ownerExecutable, globalObject) , m_heap(&m_globalObject->globalData().heap) , m_numCalleeRegisters(0) , m_numVars(0) + , m_numCapturedVars(0) , m_isConstructor(isConstructor) , m_numParameters(0) , m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable) @@ -1764,7 +1768,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlo #if ENABLE(VALUE_PROFILER) , m_executionEntryCount(0) #endif - , m_symbolTable(symTab) + , m_symbolTable(globalObject->globalData(), ownerExecutable, SharedSymbolTable::create(globalObject->globalData())) , m_alternative(alternative) , m_osrExitCounter(0) , m_optimizationDelayCounter(0) @@ -2030,13 +2034,11 @@ void CodeBlock::visitWeakReferences(SlotVisitor& visitor) performTracingFixpointIteration(visitor); } -#if ENABLE(JIT) #if ENABLE(JIT_VERBOSE_OSR) static const bool verboseUnlinking = true; #else static const bool verboseUnlinking = false; #endif -#endif // ENABLE(JIT) void CodeBlock::finalizeUnconditionally() { @@ -2222,6 +2224,7 @@ void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor) { visitor.append(&m_globalObject); visitor.append(&m_ownerExecutable); + visitor.append(&m_symbolTable); if (m_rareData) { m_rareData->m_evalCodeCache.visitAggregate(visitor); size_t regExpCount = m_rareData->m_regexps.size(); @@ -2531,7 +2534,7 @@ void CodeBlock::createActivation(CallFrame* callFrame) ASSERT(!callFrame->uncheckedR(activationRegister()).jsValue()); JSActivation* activation = JSActivation::create(callFrame->globalData(), callFrame, static_cast<FunctionExecutable*>(ownerExecutable())); callFrame->uncheckedR(activationRegister()) = JSValue(activation); - callFrame->setScopeChain(callFrame->scopeChain()->push(activation)); + callFrame->setScope(activation); } unsigned CodeBlock::addOrFindConstant(JSValue v) @@ -2579,6 +2582,7 @@ void CodeBlock::unlinkIncomingCalls() while (m_incomingCalls.begin() != m_incomingCalls.end()) m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer); } +#endif // ENABLE(JIT) #if ENABLE(LLINT) Instruction* CodeBlock::adjustPCIfAtCallSite(Instruction* potentialReturnPC) @@ -2615,7 +2619,7 @@ Instruction* CodeBlock::adjustPCIfAtCallSite(Instruction* potentialReturnPC) opcodeLength = OPCODE_LENGTH(op_call_varargs); adjustedPC = potentialReturnPC - opcodeLength; if ((returnPCOffset >= opcodeLength) - && (adjustedPC->u.pointer == bitwise_cast<void*>(llint_op_call_varargs))) { + && (adjustedPC->u.pointer == LLInt::getCodePtr(llint_op_call_varargs))) { return adjustedPC; } @@ -2623,22 +2627,37 @@ Instruction* CodeBlock::adjustPCIfAtCallSite(Instruction* potentialReturnPC) opcodeLength = OPCODE_LENGTH(op_call); adjustedPC = potentialReturnPC - opcodeLength; if ((returnPCOffset >= opcodeLength) - && (adjustedPC->u.pointer == bitwise_cast<void*>(llint_op_call) - || adjustedPC->u.pointer == bitwise_cast<void*>(llint_op_construct) - || adjustedPC->u.pointer == bitwise_cast<void*>(llint_op_call_eval))) { + && (adjustedPC->u.pointer == LLInt::getCodePtr(llint_op_call) + || adjustedPC->u.pointer == LLInt::getCodePtr(llint_op_construct) + || adjustedPC->u.pointer == LLInt::getCodePtr(llint_op_call_eval))) { return adjustedPC; } // Not a call site. No need to adjust PC. Just return the original. return potentialReturnPC; } -#endif +#endif // ENABLE(LLINT) unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddress) { + UNUSED_PARAM(exec); + UNUSED_PARAM(returnAddress); #if ENABLE(LLINT) - if (returnAddress.value() >= bitwise_cast<void*>(&llint_begin) - && returnAddress.value() <= bitwise_cast<void*>(&llint_end)) { +#if !ENABLE(LLINT_C_LOOP) + // When using the JIT, we could have addresses that are not bytecode + // addresses. We check if the return address is in the LLint glue and + // opcode handlers range here to ensure that we are looking at bytecode + // before attempting to convert the return address into a bytecode offset. + // + // In the case of the C Loop LLInt, the JIT is disabled, and the only + // valid return addresses should be bytecode PCs. So, we can and need to + // forego this check because when we do not ENABLE(COMPUTED_GOTO_OPCODES), + // then the bytecode "PC"s are actually the opcodeIDs and are not bounded + // by llint_begin and llint_end. + if (returnAddress.value() >= LLInt::getCodePtr(llint_begin) + && returnAddress.value() <= LLInt::getCodePtr(llint_end)) +#endif + { ASSERT(exec->codeBlock()); ASSERT(exec->codeBlock() == this); ASSERT(JITCode::isBaselineCode(getJITType())); @@ -2646,20 +2665,23 @@ unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddre ASSERT(instruction); instruction = adjustPCIfAtCallSite(instruction); - return bytecodeOffset(instruction); } -#else - UNUSED_PARAM(exec); -#endif +#endif // !ENABLE(LLINT) + +#if ENABLE(JIT) if (!m_rareData) return 1; Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector; if (!callIndices.size()) return 1; return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset; -} +#endif // ENABLE(JIT) + +#if !ENABLE(LLINT) && !ENABLE(JIT) + return 1; #endif +} void CodeBlock::clearEvalCache() { @@ -2721,27 +2743,27 @@ CodeBlock* FunctionCodeBlock::replacement() return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall); } -JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode, unsigned bytecodeIndex) +JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex) { if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType())) return 0; - JSObject* error = static_cast<ProgramExecutable*>(ownerExecutable())->compileOptimized(exec, scopeChainNode, bytecodeIndex); + JSObject* error = static_cast<ProgramExecutable*>(ownerExecutable())->compileOptimized(exec, scope, bytecodeIndex); return error; } -JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode, unsigned bytecodeIndex) +JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex) { if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType())) return 0; - JSObject* error = static_cast<EvalExecutable*>(ownerExecutable())->compileOptimized(exec, scopeChainNode, bytecodeIndex); + JSObject* error = static_cast<EvalExecutable*>(ownerExecutable())->compileOptimized(exec, scope, bytecodeIndex); return error; } -JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode, unsigned bytecodeIndex) +JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex) { if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType())) return 0; - JSObject* error = static_cast<FunctionExecutable*>(ownerExecutable())->compileOptimizedFor(exec, scopeChainNode, bytecodeIndex, m_isConstructor ? CodeForConstruct : CodeForCall); + JSObject* error = static_cast<FunctionExecutable*>(ownerExecutable())->compileOptimizedFor(exec, scope, bytecodeIndex, m_isConstructor ? CodeForConstruct : CodeForCall); return error; } @@ -3003,22 +3025,22 @@ bool CodeBlock::usesOpcode(OpcodeID opcodeID) return false; } -UString CodeBlock::nameForRegister(int registerNumber) +String CodeBlock::nameForRegister(int registerNumber) { SymbolTable::iterator end = m_symbolTable->end(); for (SymbolTable::iterator ptr = m_symbolTable->begin(); ptr != end; ++ptr) { if (ptr->second.getIndex() == registerNumber) - return UString(ptr->first); + return String(ptr->first); } if (needsActivation() && registerNumber == activationRegister()) - return "activation"; + return ASCIILiteral("activation"); if (registerNumber == thisRegister()) - return "this"; + return ASCIILiteral("this"); if (usesArguments()) { if (registerNumber == argumentsRegister()) - return "arguments"; + return ASCIILiteral("arguments"); if (unmodifiedArgumentsRegister(argumentsRegister()) == registerNumber) - return "real arguments"; + return ASCIILiteral("real arguments"); } if (registerNumber < 0) { int argumentPosition = -registerNumber; diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h index a8b2a5871..1d56999ff 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.h +++ b/Source/JavaScriptCore/bytecode/CodeBlock.h @@ -64,7 +64,6 @@ #include "Nodes.h" #include "RegExpObject.h" #include "StructureStubInfo.h" -#include "UString.h" #include "UnconditionalFinalizer.h" #include "ValueProfile.h" #include "Watchpoint.h" @@ -75,6 +74,7 @@ #include <wtf/RefPtr.h> #include <wtf/SegmentedVector.h> #include <wtf/Vector.h> +#include <wtf/text/WTFString.h> // Set ENABLE_BYTECODE_COMMENTS to 1 to enable recording bytecode generator // comments for the bytecodes that it generates. This will allow @@ -118,9 +118,9 @@ namespace JSC { public: enum CopyParsedBlockTag { CopyParsedBlock }; protected: - CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable*); + CodeBlock(CopyParsedBlockTag, CodeBlock& other); - CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr<SourceProvider>, unsigned sourceOffset, SymbolTable*, bool isConstructor, PassOwnPtr<CodeBlock> alternative); + CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr<SourceProvider>, unsigned sourceOffset, bool isConstructor, PassOwnPtr<CodeBlock> alternative); WriteBarrier<JSGlobalObject> m_globalObject; Heap* m_heap; @@ -229,12 +229,14 @@ namespace JSC { { return *(binarySearch<MethodCallLinkInfo, unsigned, getMethodCallLinkInfoBytecodeIndex>(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), bytecodeIndex)); } +#endif // ENABLE(JIT) #if ENABLE(LLINT) Instruction* adjustPCIfAtCallSite(Instruction*); #endif unsigned bytecodeOffset(ExecState*, ReturnAddressPtr); +#if ENABLE(JIT) unsigned bytecodeOffsetForCallAtIndex(unsigned index) { if (!m_rareData) @@ -254,6 +256,8 @@ namespace JSC { { m_incomingCalls.push(incoming); } +#endif // ENABLE(JIT) + #if ENABLE(LLINT) void linkIncomingCall(LLIntCallLinkInfo* incoming) { @@ -262,7 +266,6 @@ namespace JSC { #endif // ENABLE(LLINT) void unlinkIncomingCalls(); -#endif // ENABLE(JIT) #if ENABLE(DFG_JIT) || ENABLE(LLINT) void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap) @@ -445,7 +448,7 @@ namespace JSC { MacroAssemblerCodePtr getJITCodeWithArityCheck() { return m_jitCodeWithArityCheck; } JITCode::JITType getJITType() { return m_jitCode.jitType(); } ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); } - virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*, unsigned bytecodeIndex) = 0; + virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex) = 0; virtual void jettison() = 0; enum JITCompilationResult { AlreadyCompiled, CouldNotCompile, CompiledSuccessfully }; JITCompilationResult jitCompile(ExecState* exec) @@ -583,7 +586,7 @@ namespace JSC { void clearEvalCache(); - UString nameForRegister(int registerNumber); + String nameForRegister(int registerNumber); void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { @@ -931,7 +934,7 @@ namespace JSC { if (!codeOrigin.inlineCallFrame) return globalObject(); // FIXME: if we ever inline based on executable not function, this code will need to change. - return codeOrigin.inlineCallFrame->callee->scope()->globalObject.get(); + return codeOrigin.inlineCallFrame->callee->scope()->globalObject(); } // Jump Tables @@ -949,8 +952,7 @@ namespace JSC { StringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; } - SymbolTable* symbolTable() { return m_symbolTable; } - SharedSymbolTable* sharedSymbolTable() { ASSERT(m_codeType == FunctionCode); return static_cast<SharedSymbolTable*>(m_symbolTable); } + SharedSymbolTable* symbolTable() { return m_symbolTable.get(); } EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; } @@ -1361,7 +1363,7 @@ namespace JSC { Vector<WriteBarrier<FunctionExecutable> > m_functionDecls; Vector<WriteBarrier<FunctionExecutable> > m_functionExprs; - SymbolTable* m_symbolTable; + WriteBarrier<SharedSymbolTable> m_symbolTable; OwnPtr<CodeBlock> m_alternative; @@ -1423,18 +1425,14 @@ namespace JSC { class GlobalCodeBlock : public CodeBlock { protected: GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other) - : CodeBlock(CopyParsedBlock, other, &m_unsharedSymbolTable) - , m_unsharedSymbolTable(other.m_unsharedSymbolTable) + : CodeBlock(CopyParsedBlock, other) { } GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative) - : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, &m_unsharedSymbolTable, false, alternative) + : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, false, alternative) { } - - private: - SymbolTable m_unsharedSymbolTable; }; class ProgramCodeBlock : public GlobalCodeBlock { @@ -1451,7 +1449,7 @@ namespace JSC { #if ENABLE(JIT) protected: - virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*, unsigned bytecodeIndex); + virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex); virtual void jettison(); virtual bool jitCompileImpl(ExecState*); virtual CodeBlock* replacement(); @@ -1486,7 +1484,7 @@ namespace JSC { #if ENABLE(JIT) protected: - virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*, unsigned bytecodeIndex); + virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex); virtual void jettison(); virtual bool jitCompileImpl(ExecState*); virtual CodeBlock* replacement(); @@ -1501,30 +1499,18 @@ namespace JSC { class FunctionCodeBlock : public CodeBlock { public: FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other) - : CodeBlock(CopyParsedBlock, other, other.sharedSymbolTable()) + : CodeBlock(CopyParsedBlock, other) { - // The fact that we have to do this is yucky, but is necessary because of the - // class hierarchy issues described in the comment block for the main - // constructor, below. - sharedSymbolTable()->ref(); } - // 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, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, bool isConstructor, PassOwnPtr<CodeBlock> alternative = nullptr) - : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, SharedSymbolTable::create().leakRef(), isConstructor, alternative) - { - } - ~FunctionCodeBlock() + : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, isConstructor, alternative) { - sharedSymbolTable()->deref(); } #if ENABLE(JIT) protected: - virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*, unsigned bytecodeIndex); + virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex); virtual void jettison(); virtual bool jitCompileImpl(ExecState*); virtual CodeBlock* replacement(); diff --git a/Source/JavaScriptCore/bytecode/DFGExitProfile.h b/Source/JavaScriptCore/bytecode/DFGExitProfile.h index e0aeba2bd..45947c8af 100644 --- a/Source/JavaScriptCore/bytecode/DFGExitProfile.h +++ b/Source/JavaScriptCore/bytecode/DFGExitProfile.h @@ -58,6 +58,8 @@ inline const char* exitKindToString(ExitKind kind) return "Overflow"; case NegativeZero: return "NegativeZero"; + case OutOfBounds: + return "OutOfBounds"; case InadequateCoverage: return "InadequateCoverage"; case ArgumentsEscaped: diff --git a/Source/JavaScriptCore/bytecode/EvalCodeCache.h b/Source/JavaScriptCore/bytecode/EvalCodeCache.h index fba1d32f5..29b17dd82 100644 --- a/Source/JavaScriptCore/bytecode/EvalCodeCache.h +++ b/Source/JavaScriptCore/bytecode/EvalCodeCache.h @@ -34,7 +34,6 @@ #include "Nodes.h" #include "Parser.h" #include "SourceCode.h" -#include "UString.h" #include <wtf/HashMap.h> #include <wtf/RefPtr.h> #include <wtf/text/StringHash.h> @@ -45,32 +44,32 @@ namespace JSC { class EvalCodeCache { public: - EvalExecutable* tryGet(bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain) + EvalExecutable* tryGet(bool inStrictContext, const String& evalSource, JSScope* scope) { - if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject()) + if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && scope->begin()->isVariableObject()) return m_cacheMap.get(evalSource.impl()).get(); return 0; } - EvalExecutable* getSlow(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) + EvalExecutable* getSlow(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const String& evalSource, JSScope* scope, JSValue& exceptionValue) { EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext); - exceptionValue = evalExecutable->compile(exec, scopeChain); + exceptionValue = evalExecutable->compile(exec, scope); if (exceptionValue) return 0; - if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) + if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && scope->begin()->isVariableObject() && m_cacheMap.size() < maxCacheEntries) m_cacheMap.set(evalSource.impl(), WriteBarrier<EvalExecutable>(exec->globalData(), owner, evalExecutable)); return evalExecutable; } - - EvalExecutable* get(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) + + EvalExecutable* get(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const String& evalSource, JSScope* scope, JSValue& exceptionValue) { - EvalExecutable* evalExecutable = tryGet(inStrictContext, evalSource, scopeChain); + EvalExecutable* evalExecutable = tryGet(inStrictContext, evalSource, scope); if (!evalExecutable) - evalExecutable = getSlow(exec, owner, inStrictContext, evalSource, scopeChain, exceptionValue); + evalExecutable = getSlow(exec, owner, inStrictContext, evalSource, scope, exceptionValue); return evalExecutable; } diff --git a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp index 0df0f44e7..8f2a46879 100644 --- a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp +++ b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp @@ -27,6 +27,8 @@ #include "GetByIdStatus.h" #include "CodeBlock.h" +#include "JSScope.h" +#include "LLIntData.h" #include "LowLevelInterpreter.h" namespace JSC { @@ -39,7 +41,7 @@ GetByIdStatus GetByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned #if ENABLE(LLINT) Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex; - if (instruction[0].u.opcode == llint_op_method_check) + if (instruction[0].u.opcode == LLInt::getOpcode(llint_op_method_check)) instruction++; Structure* structure = instruction[4].u.structure.get(); diff --git a/Source/JavaScriptCore/bytecode/GlobalResolveInfo.h b/Source/JavaScriptCore/bytecode/GlobalResolveInfo.h index c466c750d..99292b7f3 100644 --- a/Source/JavaScriptCore/bytecode/GlobalResolveInfo.h +++ b/Source/JavaScriptCore/bytecode/GlobalResolveInfo.h @@ -40,7 +40,7 @@ struct GlobalResolveInfo { } WriteBarrier<Structure> structure; - unsigned offset; + PropertyOffset offset; unsigned bytecodeOffset; // Only valid in old JIT code. This means nothing in the DFG. }; diff --git a/Source/JavaScriptCore/bytecode/JumpTable.h b/Source/JavaScriptCore/bytecode/JumpTable.h index 5bbe04710..a01f90cb0 100644 --- a/Source/JavaScriptCore/bytecode/JumpTable.h +++ b/Source/JavaScriptCore/bytecode/JumpTable.h @@ -31,9 +31,9 @@ #define JumpTable_h #include "MacroAssembler.h" -#include "UString.h" #include <wtf/HashMap.h> #include <wtf/Vector.h> +#include <wtf/text/StringImpl.h> namespace JSC { diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h index 777b4876f..a63cccaec 100644 --- a/Source/JavaScriptCore/bytecode/Opcode.h +++ b/Source/JavaScriptCore/bytecode/Opcode.h @@ -30,6 +30,8 @@ #ifndef Opcode_h #define Opcode_h +#include "LLIntOpcode.h" + #include <algorithm> #include <string.h> @@ -186,9 +188,9 @@ namespace JSC { macro(op_get_pnames, 6) \ macro(op_next_pname, 7) \ \ - macro(op_push_scope, 2) \ + macro(op_push_with_scope, 2) \ macro(op_pop_scope, 1) \ - macro(op_push_new_scope, 4) \ + macro(op_push_name_scope, 4) \ \ macro(op_catch, 2) \ macro(op_throw, 2) \ @@ -198,6 +200,8 @@ namespace JSC { macro(op_profile_will_call, 2) \ macro(op_profile_did_call, 2) \ \ + FOR_EACH_LLINT_OPCODE_EXTENSION(macro) \ + \ macro(op_end, 2) // end must be the last opcode in the list #define OPCODE_ID_ENUM(opcode, length) opcode, @@ -221,13 +225,9 @@ namespace JSC { FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID); #undef VERIFY_OPCODE_ID -#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT) -#if COMPILER(RVCT) || COMPILER(INTEL) +#if ENABLE(COMPUTED_GOTO_OPCODES) typedef void* Opcode; #else - typedef const void* Opcode; -#endif -#else typedef OpcodeID Opcode; #endif diff --git a/Source/JavaScriptCore/bytecode/Operands.h b/Source/JavaScriptCore/bytecode/Operands.h index 8ea3e5b60..b0f0e692c 100644 --- a/Source/JavaScriptCore/bytecode/Operands.h +++ b/Source/JavaScriptCore/bytecode/Operands.h @@ -28,7 +28,7 @@ #include "CallFrame.h" #include "JSObject.h" -#include "ScopeChain.h" + #include <wtf/Vector.h> namespace JSC { diff --git a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp index e9456313a..35800f3dd 100644 --- a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp +++ b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp @@ -27,6 +27,7 @@ #include "PutByIdStatus.h" #include "CodeBlock.h" +#include "LLIntData.h" #include "LowLevelInterpreter.h" #include "Structure.h" #include "StructureChain.h" @@ -45,8 +46,8 @@ PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned if (!structure) return PutByIdStatus(NoInformation, 0, 0, 0, invalidOffset); - if (instruction[0].u.opcode == llint_op_put_by_id - || instruction[0].u.opcode == llint_op_put_by_id_out_of_line) { + if (instruction[0].u.opcode == LLInt::getOpcode(llint_op_put_by_id) + || instruction[0].u.opcode == LLInt::getOpcode(llint_op_put_by_id_out_of_line)) { PropertyOffset offset = structure->get(*profiledBlock->globalData(), ident); if (!isValidOffset(offset)) return PutByIdStatus(NoInformation, 0, 0, 0, invalidOffset); @@ -56,10 +57,10 @@ PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned ASSERT(structure->transitionWatchpointSetHasBeenInvalidated()); - ASSERT(instruction[0].u.opcode == llint_op_put_by_id_transition_direct - || instruction[0].u.opcode == llint_op_put_by_id_transition_normal - || instruction[0].u.opcode == llint_op_put_by_id_transition_direct_out_of_line - || instruction[0].u.opcode == llint_op_put_by_id_transition_normal_out_of_line); + ASSERT(instruction[0].u.opcode == LLInt::getOpcode(llint_op_put_by_id_transition_direct) + || instruction[0].u.opcode == LLInt::getOpcode(llint_op_put_by_id_transition_normal) + || instruction[0].u.opcode == LLInt::getOpcode(llint_op_put_by_id_transition_direct_out_of_line) + || instruction[0].u.opcode == LLInt::getOpcode(llint_op_put_by_id_transition_normal_out_of_line)); Structure* newStructure = instruction[6].u.structure.get(); StructureChain* chain = instruction[7].u.structureChain.get(); diff --git a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp index 783e7c615..c9fd7dca2 100644 --- a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp +++ b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp @@ -52,8 +52,8 @@ static ResolveGlobalStatus computeForLLInt(CodeBlock* codeBlock, unsigned byteco { #if ENABLE(LLINT) Instruction* instruction = codeBlock->instructions().begin() + bytecodeIndex; - - ASSERT(instruction[0].u.opcode == llint_op_resolve_global); + + ASSERT(instruction[0].u.opcode == LLInt::getOpcode(op_resolve_global)); Structure* structure = instruction[3].u.structure.get(); if (!structure) diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.h b/Source/JavaScriptCore/bytecode/SpeculatedType.h index 4ecc53776..9d2c61ae8 100644 --- a/Source/JavaScriptCore/bytecode/SpeculatedType.h +++ b/Source/JavaScriptCore/bytecode/SpeculatedType.h @@ -82,6 +82,16 @@ inline bool isCellSpeculation(SpeculatedType value) return !!(value & SpecCell) && !(value & ~SpecCell); } +inline bool isNonStringCellSpeculation(SpeculatedType value) +{ + return !!(value & (SpecCell & ~SpecString)) && !(value & ~(SpecCell & ~SpecString)); +} + +inline bool isNonStringCellOrOtherSpeculation(SpeculatedType value) +{ + return !!(value & ((SpecCell & ~SpecString) | SpecOther)) && !(value & ~((SpecCell & ~SpecString) | SpecOther)); +} + inline bool isObjectSpeculation(SpeculatedType value) { return !!(value & SpecObjectMask) && !(value & ~SpecObjectMask); diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp index f66860a45..9238fefdc 100644 --- a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp +++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp @@ -28,7 +28,7 @@ #include "JSObject.h" #include "PolymorphicPutByIdList.h" -#include "ScopeChain.h" + namespace JSC { |