summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp')
-rw-r--r--Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp368
1 files changed, 165 insertions, 203 deletions
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
index 1dfb5ac6a..53defbfb3 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012-2013, 2015-2016 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,191 +28,52 @@
#include "UnlinkedCodeBlock.h"
#include "BytecodeGenerator.h"
+#include "BytecodeRewriter.h"
#include "ClassInfo.h"
#include "CodeCache.h"
-#include "Executable.h"
+#include "ExecutableInfo.h"
+#include "FunctionOverrides.h"
+#include "JSCInlines.h"
#include "JSString.h"
-#include "Operations.h"
#include "Parser.h"
+#include "PreciseJumpTargetsInlines.h"
#include "SourceProvider.h"
#include "Structure.h"
#include "SymbolTable.h"
+#include "UnlinkedEvalCodeBlock.h"
+#include "UnlinkedFunctionCodeBlock.h"
#include "UnlinkedInstructionStream.h"
+#include "UnlinkedModuleProgramCodeBlock.h"
+#include "UnlinkedProgramCodeBlock.h"
#include <wtf/DataLog.h>
namespace JSC {
-const ClassInfo UnlinkedFunctionExecutable::s_info = { "UnlinkedFunctionExecutable", 0, 0, 0, CREATE_METHOD_TABLE(UnlinkedFunctionExecutable) };
-const ClassInfo UnlinkedCodeBlock::s_info = { "UnlinkedCodeBlock", 0, 0, 0, CREATE_METHOD_TABLE(UnlinkedCodeBlock) };
-const ClassInfo UnlinkedGlobalCodeBlock::s_info = { "UnlinkedGlobalCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedGlobalCodeBlock) };
-const ClassInfo UnlinkedProgramCodeBlock::s_info = { "UnlinkedProgramCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedProgramCodeBlock) };
-const ClassInfo UnlinkedEvalCodeBlock::s_info = { "UnlinkedEvalCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedEvalCodeBlock) };
-const ClassInfo UnlinkedFunctionCodeBlock::s_info = { "UnlinkedFunctionCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedFunctionCodeBlock) };
+const ClassInfo UnlinkedCodeBlock::s_info = { "UnlinkedCodeBlock", 0, 0, CREATE_METHOD_TABLE(UnlinkedCodeBlock) };
-static UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
-{
- RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(&vm, source, executable->parameters(), executable->name(), executable->isInStrictContext() ? JSParseStrict : JSParseNormal, JSParseFunctionCode, error);
-
- if (!body) {
- ASSERT(error.m_type != ParserError::ErrorNone);
- return 0;
- }
-
- if (executable->forceUsesArguments())
- body->setUsesArguments();
- body->finishParsing(executable->parameters(), executable->name(), executable->functionNameIsInScopeToggle());
- executable->recordParse(body->features(), body->hasCapturedVariables());
-
- UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(body->needsActivation(), body->usesEval(), body->isStrictMode(), kind == CodeForConstruct));
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(vm, body.get(), result, debuggerMode, profilerMode)));
- error = generator->generate();
- body->destroyData();
- if (error.m_type != ParserError::ErrorNone)
- return 0;
- return result;
-}
-
-unsigned UnlinkedCodeBlock::addOrFindConstant(JSValue v)
-{
- unsigned numberOfConstants = numberOfConstantRegisters();
- for (unsigned i = 0; i < numberOfConstants; ++i) {
- if (getConstant(FirstConstantRegisterIndex + i) == v)
- return i;
- }
- return addConstant(v);
-}
-
-UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, FunctionBodyNode* node, bool isFromGlobalCode)
- : Base(*vm, structure)
- , m_numCapturedVariables(node->capturedVariableCount())
- , m_forceUsesArguments(node->usesArguments())
- , m_isInStrictContext(node->isStrictMode())
- , m_hasCapturedVariables(node->hasCapturedVariables())
- , m_isFromGlobalCode(isFromGlobalCode)
- , m_name(node->ident())
- , m_inferredName(node->inferredName())
- , m_parameters(node->parameters())
- , m_firstLineOffset(node->firstLine() - source.firstLine())
- , m_lineCount(node->lastLine() - node->firstLine())
- , m_unlinkedFunctionNameStart(node->functionNameStart() - source.startOffset())
- , m_unlinkedBodyStartColumn(node->startColumn())
- , m_unlinkedBodyEndColumn(m_lineCount ? node->endColumn() : node->endColumn() - node->startColumn())
- , m_startOffset(node->source().startOffset() - source.startOffset())
- , m_sourceLength(node->source().length())
- , m_features(node->features())
- , m_functionNameIsInScopeToggle(node->functionNameIsInScopeToggle())
-{
-}
-
-size_t UnlinkedFunctionExecutable::parameterCount() const
-{
- return m_parameters->size();
-}
-
-void UnlinkedFunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
- UnlinkedFunctionExecutable* thisObject = jsCast<UnlinkedFunctionExecutable*>(cell);
- ASSERT_GC_OBJECT_INHERITS(thisObject, info());
- COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
- ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
- Base::visitChildren(thisObject, visitor);
- visitor.append(&thisObject->m_codeBlockForCall);
- visitor.append(&thisObject->m_codeBlockForConstruct);
- visitor.append(&thisObject->m_nameValue);
- visitor.append(&thisObject->m_symbolTableForCall);
- visitor.append(&thisObject->m_symbolTableForConstruct);
-}
-
-FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, const SourceCode& source, size_t lineOffset, size_t sourceOffset)
-{
- unsigned firstLine = lineOffset + m_firstLineOffset;
- unsigned startOffset = sourceOffset + m_startOffset;
- bool startColumnIsOnFirstSourceLine = !m_firstLineOffset;
- unsigned startColumn = m_unlinkedBodyStartColumn + (startColumnIsOnFirstSourceLine ? source.startColumn() : 1);
- bool endColumnIsOnStartLine = !m_lineCount;
- unsigned endColumn = m_unlinkedBodyEndColumn + (endColumnIsOnStartLine ? startColumn : 1);
- SourceCode code(source.provider(), startOffset, startOffset + m_sourceLength, firstLine, startColumn);
- return FunctionExecutable::create(vm, code, this, firstLine, firstLine + m_lineCount, startColumn, endColumn);
-}
-
-UnlinkedFunctionExecutable* UnlinkedFunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger*, const SourceCode& source, JSObject** exception)
-{
- ParserError error;
- VM& vm = exec->vm();
- CodeCache* codeCache = vm.codeCache();
- UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(vm, name, source, error);
-
- if (exec->lexicalGlobalObject()->hasDebugger())
- exec->lexicalGlobalObject()->debugger()->sourceParsed(exec, source.provider(), error.m_line, error.m_message);
-
- if (error.m_type != ParserError::ErrorNone) {
- *exception = error.toErrorObject(exec->lexicalGlobalObject(), source);
- return 0;
- }
-
- return executable;
-}
-
-UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(VM& vm, const SourceCode& source, CodeSpecializationKind specializationKind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
-{
- switch (specializationKind) {
- case CodeForCall:
- if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForCall.get())
- return codeBlock;
- break;
- case CodeForConstruct:
- if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForConstruct.get())
- return codeBlock;
- break;
- }
-
- UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(vm, this, source, specializationKind, debuggerMode, profilerMode, error);
-
- if (error.m_type != ParserError::ErrorNone)
- return 0;
-
- switch (specializationKind) {
- case CodeForCall:
- m_codeBlockForCall.set(vm, this, result);
- m_symbolTableForCall.set(vm, this, result->symbolTable());
- break;
- case CodeForConstruct:
- m_codeBlockForConstruct.set(vm, this, result);
- m_symbolTableForConstruct.set(vm, this, result->symbolTable());
- break;
- }
- return result;
-}
-
-String UnlinkedFunctionExecutable::paramString() const
-{
- FunctionParameters& parameters = *m_parameters;
- StringBuilder builder;
- for (size_t pos = 0; pos < parameters.size(); ++pos) {
- if (!builder.isEmpty())
- builder.appendLiteral(", ");
- parameters.at(pos)->toString(builder);
- }
- return builder.toString();
-}
-
-UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
+UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info, DebuggerMode debuggerMode)
: Base(*vm, structure)
, m_numVars(0)
- , m_numCalleeRegisters(0)
+ , m_numCalleeLocals(0)
, m_numParameters(0)
- , m_vm(vm)
- , m_argumentsRegister(VirtualRegister())
, m_globalObjectRegister(VirtualRegister())
- , m_needsFullScopeChain(info.m_needsActivation)
- , m_usesEval(info.m_usesEval)
- , m_isNumericCompareFunction(false)
- , m_isStrictMode(info.m_isStrictMode)
- , m_isConstructor(info.m_isConstructor)
+ , m_usesEval(info.usesEval())
+ , m_isStrictMode(info.isStrictMode())
+ , m_isConstructor(info.isConstructor())
, m_hasCapturedVariables(false)
- , m_firstLine(0)
+ , m_isBuiltinFunction(info.isBuiltinFunction())
+ , m_superBinding(static_cast<unsigned>(info.superBinding()))
+ , m_scriptMode(static_cast<unsigned>(info.scriptMode()))
+ , m_isArrowFunctionContext(info.isArrowFunctionContext())
+ , m_isClassContext(info.isClassContext())
+ , m_wasCompiledWithDebuggingOpcodes(debuggerMode == DebuggerMode::DebuggerOn || Options::forceDebuggerBytecodeGeneration())
+ , m_constructorKind(static_cast<unsigned>(info.constructorKind()))
+ , m_derivedContextType(static_cast<unsigned>(info.derivedContextType()))
+ , m_evalContextType(static_cast<unsigned>(info.evalContextType()))
, m_lineCount(0)
, m_endColumn(UINT_MAX)
+ , m_didOptimize(MixedTriState)
+ , m_parseMode(info.parseMode())
, m_features(0)
, m_codeType(codeType)
, m_arrayProfileCount(0)
@@ -220,32 +81,38 @@ UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType code
, m_objectAllocationProfileCount(0)
, m_valueProfileCount(0)
, m_llintCallLinkInfoCount(0)
-#if ENABLE(BYTECODE_COMMENTS)
- , m_bytecodeCommentIterator(0)
-#endif
{
-
+ for (auto& constantRegisterIndex : m_linkTimeConstants)
+ constantRegisterIndex = 0;
+ ASSERT(m_constructorKind == static_cast<unsigned>(info.constructorKind()));
}
void UnlinkedCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
UnlinkedCodeBlock* thisObject = jsCast<UnlinkedCodeBlock*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
- COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
- ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
Base::visitChildren(thisObject, visitor);
- visitor.append(&thisObject->m_symbolTable);
+ auto locker = holdLock(*thisObject);
for (FunctionExpressionVector::iterator ptr = thisObject->m_functionDecls.begin(), end = thisObject->m_functionDecls.end(); ptr != end; ++ptr)
- visitor.append(ptr);
+ visitor.append(*ptr);
for (FunctionExpressionVector::iterator ptr = thisObject->m_functionExprs.begin(), end = thisObject->m_functionExprs.end(); ptr != end; ++ptr)
- visitor.append(ptr);
+ visitor.append(*ptr);
visitor.appendValues(thisObject->m_constantRegisters.data(), thisObject->m_constantRegisters.size());
+ if (thisObject->m_unlinkedInstructions)
+ visitor.reportExtraMemoryVisited(thisObject->m_unlinkedInstructions->sizeInBytes());
if (thisObject->m_rareData) {
for (size_t i = 0, end = thisObject->m_rareData->m_regexps.size(); i != end; i++)
- visitor.append(&thisObject->m_rareData->m_regexps[i]);
+ visitor.append(thisObject->m_rareData->m_regexps[i]);
}
}
+size_t UnlinkedCodeBlock::estimatedSize(JSCell* cell)
+{
+ UnlinkedCodeBlock* thisObject = jsCast<UnlinkedCodeBlock*>(cell);
+ size_t extraSize = thisObject->m_unlinkedInstructions ? thisObject->m_unlinkedInstructions->sizeInBytes() : 0;
+ return Base::estimatedSize(cell) + extraSize;
+}
+
int UnlinkedCodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
{
ASSERT(bytecodeOffset < instructions().count());
@@ -258,8 +125,8 @@ int UnlinkedCodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
return line;
}
-inline void UnlinkedCodeBlock::getLineAndColumn(ExpressionRangeInfo& info,
- unsigned& line, unsigned& column)
+inline void UnlinkedCodeBlock::getLineAndColumn(const ExpressionRangeInfo& info,
+ unsigned& line, unsigned& column) const
{
switch (info.mode) {
case ExpressionRangeInfo::FatLineMode:
@@ -292,6 +159,7 @@ static void dumpLineColumnEntry(size_t index, const UnlinkedInstructionStream& i
case DidReachBreakpoint: event = " DidReachBreakpoint"; break;
case WillLeaveCallFrame: event = " WillLeaveCallFrame"; break;
case WillExecuteStatement: event = " WillExecuteStatement"; break;
+ case WillExecuteExpression: event = " WillExecuteExpression"; break;
}
}
dataLogF(" [%zu] pc %u @ line %u col %u : %s%s\n", index, instructionOffset, line, column, opcodeNames[opcode], event);
@@ -315,7 +183,7 @@ void UnlinkedCodeBlock::dumpExpressionRangeInfo()
#endif
void UnlinkedCodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset,
- int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
+ int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column) const
{
ASSERT(bytecodeOffset < instructions().count());
@@ -328,7 +196,7 @@ void UnlinkedCodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset
return;
}
- Vector<ExpressionRangeInfo>& expressionInfo = m_expressionInfo;
+ const Vector<ExpressionRangeInfo>& expressionInfo = m_expressionInfo;
int low = 0;
int high = expressionInfo.size();
@@ -343,7 +211,7 @@ void UnlinkedCodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset
if (!low)
low = 1;
- ExpressionRangeInfo& info = expressionInfo[low - 1];
+ const ExpressionRangeInfo& info = expressionInfo[low - 1];
startOffset = info.startOffset;
endOffset = info.endOffset;
divot = info.divotPoint;
@@ -404,51 +272,145 @@ void UnlinkedCodeBlock::addExpressionInfo(unsigned instructionOffset,
m_expressionInfo.append(info);
}
-void UnlinkedProgramCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
+bool UnlinkedCodeBlock::typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned& startDivot, unsigned& endDivot)
{
- UnlinkedProgramCodeBlock* thisObject = jsCast<UnlinkedProgramCodeBlock*>(cell);
- ASSERT_GC_OBJECT_INHERITS(thisObject, info());
- COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
- ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
- Base::visitChildren(thisObject, visitor);
- for (size_t i = 0, end = thisObject->m_functionDeclarations.size(); i != end; i++)
- visitor.append(&thisObject->m_functionDeclarations[i].second);
+ static const bool verbose = false;
+ if (!m_rareData) {
+ if (verbose)
+ dataLogF("Don't have assignment info for offset:%u\n", bytecodeOffset);
+ startDivot = UINT_MAX;
+ endDivot = UINT_MAX;
+ return false;
+ }
+
+ auto iter = m_rareData->m_typeProfilerInfoMap.find(bytecodeOffset);
+ if (iter == m_rareData->m_typeProfilerInfoMap.end()) {
+ if (verbose)
+ dataLogF("Don't have assignment info for offset:%u\n", bytecodeOffset);
+ startDivot = UINT_MAX;
+ endDivot = UINT_MAX;
+ return false;
+ }
+
+ RareData::TypeProfilerExpressionRange& range = iter->value;
+ startDivot = range.m_startDivot;
+ endDivot = range.m_endDivot;
+ return true;
}
-UnlinkedCodeBlock::~UnlinkedCodeBlock()
+void UnlinkedCodeBlock::addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot)
{
+ createRareDataIfNecessary();
+ RareData::TypeProfilerExpressionRange range;
+ range.m_startDivot = startDivot;
+ range.m_endDivot = endDivot;
+ m_rareData->m_typeProfilerInfoMap.set(instructionOffset, range);
}
-void UnlinkedProgramCodeBlock::destroy(JSCell* cell)
+UnlinkedCodeBlock::~UnlinkedCodeBlock()
{
- jsCast<UnlinkedProgramCodeBlock*>(cell)->~UnlinkedProgramCodeBlock();
}
-void UnlinkedEvalCodeBlock::destroy(JSCell* cell)
+void UnlinkedCodeBlock::setInstructions(std::unique_ptr<UnlinkedInstructionStream> instructions)
{
- jsCast<UnlinkedEvalCodeBlock*>(cell)->~UnlinkedEvalCodeBlock();
+ ASSERT(instructions);
+ {
+ auto locker = holdLock(*this);
+ m_unlinkedInstructions = WTFMove(instructions);
+ }
+ Heap::heap(this)->reportExtraMemoryAllocated(m_unlinkedInstructions->sizeInBytes());
}
-void UnlinkedFunctionCodeBlock::destroy(JSCell* cell)
+const UnlinkedInstructionStream& UnlinkedCodeBlock::instructions() const
{
- jsCast<UnlinkedFunctionCodeBlock*>(cell)->~UnlinkedFunctionCodeBlock();
+ ASSERT(m_unlinkedInstructions.get());
+ return *m_unlinkedInstructions;
}
-void UnlinkedFunctionExecutable::destroy(JSCell* cell)
+UnlinkedHandlerInfo* UnlinkedCodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler requiredHandler)
{
- jsCast<UnlinkedFunctionExecutable*>(cell)->~UnlinkedFunctionExecutable();
+ return handlerForIndex(bytecodeOffset, requiredHandler);
}
-void UnlinkedCodeBlock::setInstructions(std::unique_ptr<UnlinkedInstructionStream> instructions)
+UnlinkedHandlerInfo* UnlinkedCodeBlock::handlerForIndex(unsigned index, RequiredHandler requiredHandler)
{
- m_unlinkedInstructions = std::move(instructions);
+ if (!m_rareData)
+ return nullptr;
+ return UnlinkedHandlerInfo::handlerForIndex(m_rareData->m_exceptionHandlers, index, requiredHandler);
}
-const UnlinkedInstructionStream& UnlinkedCodeBlock::instructions() const
+void UnlinkedCodeBlock::applyModification(BytecodeRewriter& rewriter)
{
- ASSERT(m_unlinkedInstructions.get());
- return *m_unlinkedInstructions;
+ // Before applying the changes, we adjust the jumps based on the original bytecode offset, the offset to the jump target, and
+ // the insertion information.
+
+ BytecodeGraph<UnlinkedCodeBlock>& graph = rewriter.graph();
+ UnlinkedInstruction* instructionsBegin = graph.instructions().begin();
+
+ for (int bytecodeOffset = 0, instructionCount = graph.instructions().size(); bytecodeOffset < instructionCount;) {
+ UnlinkedInstruction* current = instructionsBegin + bytecodeOffset;
+ OpcodeID opcodeID = current[0].u.opcode;
+ extractStoredJumpTargetsForBytecodeOffset(this, vm()->interpreter, instructionsBegin, bytecodeOffset, [&](int32_t& relativeOffset) {
+ relativeOffset = rewriter.adjustJumpTarget(bytecodeOffset, bytecodeOffset + relativeOffset);
+ });
+ bytecodeOffset += opcodeLength(opcodeID);
+ }
+
+ // Then, exception handlers should be adjusted.
+ if (m_rareData) {
+ for (UnlinkedHandlerInfo& handler : m_rareData->m_exceptionHandlers) {
+ handler.target = rewriter.adjustAbsoluteOffset(handler.target);
+ handler.start = rewriter.adjustAbsoluteOffset(handler.start);
+ handler.end = rewriter.adjustAbsoluteOffset(handler.end);
+ }
+
+ for (size_t i = 0; i < m_rareData->m_opProfileControlFlowBytecodeOffsets.size(); ++i)
+ m_rareData->m_opProfileControlFlowBytecodeOffsets[i] = rewriter.adjustAbsoluteOffset(m_rareData->m_opProfileControlFlowBytecodeOffsets[i]);
+
+ if (!m_rareData->m_typeProfilerInfoMap.isEmpty()) {
+ HashMap<unsigned, RareData::TypeProfilerExpressionRange> adjustedTypeProfilerInfoMap;
+ for (auto& entry : m_rareData->m_typeProfilerInfoMap)
+ adjustedTypeProfilerInfoMap.set(rewriter.adjustAbsoluteOffset(entry.key), entry.value);
+ m_rareData->m_typeProfilerInfoMap.swap(adjustedTypeProfilerInfoMap);
+ }
+ }
+
+ for (size_t i = 0; i < m_propertyAccessInstructions.size(); ++i)
+ m_propertyAccessInstructions[i] = rewriter.adjustAbsoluteOffset(m_propertyAccessInstructions[i]);
+
+ for (size_t i = 0; i < m_expressionInfo.size(); ++i)
+ m_expressionInfo[i].instructionOffset = rewriter.adjustAbsoluteOffset(m_expressionInfo[i].instructionOffset);
+
+ // Then, modify the unlinked instructions.
+ rewriter.applyModification();
+
+ // And recompute the jump target based on the modified unlinked instructions.
+ m_jumpTargets.clear();
+ recomputePreciseJumpTargets(this, graph.instructions().begin(), graph.instructions().size(), m_jumpTargets);
}
+void UnlinkedCodeBlock::shrinkToFit()
+{
+ auto locker = holdLock(*this);
+
+ m_jumpTargets.shrinkToFit();
+ m_identifiers.shrinkToFit();
+ m_bitVectors.shrinkToFit();
+ m_constantRegisters.shrinkToFit();
+ m_constantsSourceCodeRepresentation.shrinkToFit();
+ m_functionDecls.shrinkToFit();
+ m_functionExprs.shrinkToFit();
+ m_propertyAccessInstructions.shrinkToFit();
+ m_expressionInfo.shrinkToFit();
+
+ if (m_rareData) {
+ m_rareData->m_exceptionHandlers.shrinkToFit();
+ m_rareData->m_regexps.shrinkToFit();
+ m_rareData->m_constantBuffers.shrinkToFit();
+ m_rareData->m_switchJumpTables.shrinkToFit();
+ m_rareData->m_stringSwitchJumpTables.shrinkToFit();
+ m_rareData->m_expressionInfoFatPositions.shrinkToFit();
+ }
}
+} // namespace JSC