📄 codeblock.cpp
字号:
} if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) { vPC[4].u.structure->ref(); vPC[5].u.structure->ref(); vPC[6].u.structureChain->ref(); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) { vPC[4].u.structure->ref(); return; } // These instructions don't ref their Structures. 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(){ 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(); for (size_t i = 0; i < m_rareData->m_unexpectedConstants.size(); ++i) { if (!m_rareData->m_unexpectedConstants[i].marked()) m_rareData->m_unexpectedConstants[i].mark(); } m_rareData->m_evalCodeCache.mark(); }}void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame){ if (m_exceptionInfo) return; ScopeChainNode* scopeChain = callFrame->scopeChain(); if (m_needsFullScopeChain) { ScopeChain sc(scopeChain); int scopeDelta = sc.localDepth(); if (m_codeType == EvalCode) scopeDelta -= static_cast<EvalCodeBlock*>(this)->baseScopeDepth(); else if (m_codeType == FunctionCode) scopeDelta++; // Compilation of function code assumes activation is not on the scope chain yet. ASSERT(scopeDelta >= 0); while (scopeDelta--) 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(newCodeBlock.m_jitCode.codeSize == m_jitCode.codeSize);#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(newCodeBlock.m_jitCode.codeSize == m_jitCode.codeSize);#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(); }}HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset){ ASSERT(bytecodeOffset < m_instructionCount); if (!m_rareData) return 0; Vector<HandlerInfo>& exceptionHandlers = m_rareData->m_exceptionHandlers; for (size_t i = 0; i < exceptionHandlers.size(); ++i) { // Handlers are ordered innermost first, so the first handler we encounter // that contains the source address is the correct handler to use. if (exceptionHandlers[i].start <= bytecodeOffset && exceptionHandlers[i].end >= bytecodeOffset) return &exceptionHandlers[i]; } return 0;}int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset){ ASSERT(bytecodeOffset < m_instructionCount); reparseForExceptionInfoIfNecessary(callFrame); ASSERT(m_exceptionInfo); if (!m_exceptionInfo->m_lineInfo.size()) return m_ownerNode->source().firstLine(); // Empty function int low = 0; int high = m_exceptionInfo->m_lineInfo.size(); while (low < high) { int mid = low + (high - low) / 2; if (m_exceptionInfo->m_lineInfo[mid].instructionOffset <= bytecodeOffset) low = mid + 1; else high = mid; } if (!low) return m_ownerNode->source().firstLine(); return m_exceptionInfo->m_lineInfo[low - 1].lineNumber;}int CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset){ ASSERT(bytecodeOffset < m_instructionCount); reparseForExceptionInfoIfNecessary(callFrame); ASSERT(m_exceptionInfo); if (!m_exceptionInfo->m_expressionInfo.size()) { // We didn't think anything could throw. Apparently we were wrong. startOffset = 0; endOffset = 0; divot = 0; return lineNumberForBytecodeOffset(callFrame, bytecodeOffset); } int low = 0; int high = m_exceptionInfo->m_expressionInfo.size(); while (low < high) { int mid = low + (high - low) / 2; if (m_exceptionInfo->m_expressionInfo[mid].instructionOffset <= bytecodeOffset) low = mid + 1; else high = mid; } ASSERT(low); if (!low) { startOffset = 0; endOffset = 0; divot = 0; return lineNumberForBytecodeOffset(callFrame, bytecodeOffset); } startOffset = m_exceptionInfo->m_expressionInfo[low - 1].startOffset; endOffset = m_exceptionInfo->m_expressionInfo[low - 1].endOffset; divot = m_exceptionInfo->m_expressionInfo[low - 1].divotPoint + m_sourceOffset; return lineNumberForBytecodeOffset(callFrame, bytecodeOffset);}bool CodeBlock::getByIdExceptionInfoForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, OpcodeID& opcodeID){ ASSERT(bytecodeOffset < m_instructionCount); reparseForExceptionInfoIfNecessary(callFrame); ASSERT(m_exceptionInfo); if (!m_exceptionInfo->m_getByIdExceptionInfo.size()) return false; int low = 0; int high = m_exceptionInfo->m_getByIdExceptionInfo.size(); while (low < high) { int mid = low + (high - low) / 2; if (m_exceptionInfo->m_getByIdExceptionInfo[mid].bytecodeOffset <= bytecodeOffset) low = mid + 1; else high = mid; } if (!low || m_exceptionInfo->m_getByIdExceptionInfo[low - 1].bytecodeOffset != bytecodeOffset) return false; opcodeID = m_exceptionInfo->m_getByIdExceptionInfo[low - 1].isOpConstruct ? op_construct : op_instanceof; return true;}#if ENABLE(JIT)bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex){ ASSERT(bytecodeOffset < m_instructionCount); if (!m_rareData || !m_rareData->m_functionRegisterInfos.size()) return false; int low = 0; int high = m_rareData->m_functionRegisterInfos.size(); while (low < high) { int mid = low + (high - low) / 2; if (m_rareData->m_functionRegisterInfos[mid].bytecodeOffset <= bytecodeOffset) low = mid + 1; else high = mid; } if (!low || m_rareData->m_functionRegisterInfos[low - 1].bytecodeOffset != bytecodeOffset) return false; functionRegisterIndex = m_rareData->m_functionRegisterInfos[low - 1].functionRegisterIndex; return true;}#endif#if !ENABLE(JIT)bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset){ if (m_globalResolveInstructions.isEmpty()) return false; int low = 0; int high = m_globalResolveInstructions.size(); while (low < high) { int mid = low + (high - low) / 2; if (m_globalResolveInstructions[mid] <= bytecodeOffset) low = mid + 1; else high = mid; } if (!low || m_globalResolveInstructions[low - 1] != bytecodeOffset) return false; return true;}#elsebool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset){ if (m_globalResolveInfos.isEmpty()) return false; int low = 0; int high = m_globalResolveInfos.size(); while (low < high) { int mid = low + (high - low) / 2; if (m_globalResolveInfos[mid].bytecodeOffset <= bytecodeOffset) low = mid + 1; else high = mid; } if (!low || m_globalResolveInfos[low - 1].bytecodeOffset != bytecodeOffset) return false; return true;}#endif#if ENABLE(JIT)void CodeBlock::setJITCode(JITCodeRef& jitCode){ m_jitCode = jitCode;#if !ENABLE(OPCODE_SAMPLING) if (!BytecodeGenerator::dumpsGeneratedCode()) m_instructions.clear();#endif}#endifvoid CodeBlock::shrinkToFit(){ m_instructions.shrinkToFit();#if !ENABLE(JIT) m_propertyAccessInstructions.shrinkToFit(); m_globalResolveInstructions.shrinkToFit();#else m_structureStubInfos.shrinkToFit(); m_globalResolveInfos.shrinkToFit(); m_callLinkInfos.shrinkToFit(); m_linkedCallerList.shrinkToFit();#endif m_identifiers.shrinkToFit(); m_functionExpressions.shrinkToFit(); m_constantRegisters.shrinkToFit(); if (m_exceptionInfo) { m_exceptionInfo->m_expressionInfo.shrinkToFit(); m_exceptionInfo->m_lineInfo.shrinkToFit(); m_exceptionInfo->m_getByIdExceptionInfo.shrinkToFit(); } if (m_rareData) { m_rareData->m_exceptionHandlers.shrinkToFit(); m_rareData->m_functions.shrinkToFit(); m_rareData->m_unexpectedConstants.shrinkToFit(); m_rareData->m_regexps.shrinkToFit(); m_rareData->m_immediateSwitchJumpTables.shrinkToFit(); m_rareData->m_characterSwitchJumpTables.shrinkToFit(); m_rareData->m_stringSwitchJumpTables.shrinkToFit();#if ENABLE(JIT) m_rareData->m_functionRegisterInfos.shrinkToFit();#endif }}} // namespace JSC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -