+ m_rareData->m_expressionInfo.shrinkToFit();
+ m_rareData->m_lineInfo.shrinkToFit();
+ }
+}
+
+void CodeBlock::createActivation(CallFrame* callFrame)
+{
+ ASSERT(codeType() == FunctionCode);
+ ASSERT(needsFullScopeChain());
+ 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));
+}
+
+unsigned CodeBlock::addOrFindConstant(JSValue v)
+{
+ unsigned numberOfConstants = numberOfConstantRegisters();
+ for (unsigned i = 0; i < numberOfConstants; ++i) {
+ if (getConstant(FirstConstantRegisterIndex + i) == v)
+ return i;
+ }
+ return addConstant(v);
+}
+
+#if ENABLE(JIT)
+void CodeBlock::unlinkCalls()
+{
+ if (!!m_alternative)
+ m_alternative->unlinkCalls();
+#if ENABLE(LLINT)
+ for (size_t i = 0; i < m_llintCallLinkInfos.size(); ++i) {
+ if (m_llintCallLinkInfos[i].isLinked())
+ m_llintCallLinkInfos[i].unlink();
+ }
+#endif
+ if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size()))
+ return;
+ if (!m_globalData->canUseJIT())
+ return;
+ RepatchBuffer repatchBuffer(this);
+ for (size_t i = 0; i < m_callLinkInfos.size(); i++) {
+ if (!m_callLinkInfos[i].isLinked())
+ continue;
+ m_callLinkInfos[i].unlink(*m_globalData, repatchBuffer);
+ }
+}
+
+void CodeBlock::unlinkIncomingCalls()
+{
+#if ENABLE(LLINT)
+ while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
+ m_incomingLLIntCalls.begin()->unlink();
+#endif
+ if (m_incomingCalls.isEmpty())
+ return;
+ RepatchBuffer repatchBuffer(this);
+ while (m_incomingCalls.begin() != m_incomingCalls.end())
+ m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer);
+}
+
+unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddress)
+{
+#if ENABLE(LLINT)
+ if (returnAddress.value() >= bitwise_cast<void*>(&llint_begin)
+ && returnAddress.value() <= bitwise_cast<void*>(&llint_end)) {
+ ASSERT(exec->codeBlock());
+ ASSERT(exec->codeBlock() == this);
+ ASSERT(JITCode::isBaselineCode(getJITType()));
+ Instruction* instruction = exec->currentVPC();
+ ASSERT(instruction);
+
+ // The LLInt stores the PC after the call instruction rather than the PC of
+ // the call instruction. This requires some correcting. We rely on the fact
+ // that the preceding instruction must be one of the call instructions, so
+ // either it's a call_varargs or it's a call, construct, or eval.
+ ASSERT(OPCODE_LENGTH(op_call_varargs) <= OPCODE_LENGTH(op_call));
+ ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct));
+ ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_eval));
+ if (instruction[-OPCODE_LENGTH(op_call_varargs)].u.pointer == bitwise_cast<void*>(llint_op_call_varargs)) {
+ // We know that the preceding instruction must be op_call_varargs because there is no way that
+ // the pointer to the call_varargs could be an operand to the call.
+ instruction -= OPCODE_LENGTH(op_call_varargs);
+ ASSERT(instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast<void*>(llint_op_call)
+ && instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast<void*>(llint_op_construct)
+ && instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast<void*>(llint_op_call_eval));
+ } else {
+ // Must be that the last instruction was some op_call.
+ ASSERT(instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast<void*>(llint_op_call)
+ || instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast<void*>(llint_op_construct)
+ || instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast<void*>(llint_op_call_eval));
+ instruction -= OPCODE_LENGTH(op_call);
+ }
+
+ return bytecodeOffset(instruction);
+ }
+#else
+ UNUSED_PARAM(exec);
+#endif
+ 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
+
+void CodeBlock::clearEvalCache()
+{
+ if (!!m_alternative)
+ m_alternative->clearEvalCache();
+ if (!m_rareData)
+ return;
+ m_rareData->m_evalCodeCache.clear();
+}
+
+template<typename T>
+inline void replaceExistingEntries(Vector<T>& target, Vector<T>& source)
+{
+ ASSERT(target.size() <= source.size());
+ for (size_t i = 0; i < target.size(); ++i)
+ target[i] = source[i];
+}
+
+void CodeBlock::copyPostParseDataFrom(CodeBlock* alternative)
+{
+ if (!alternative)
+ return;
+
+ replaceExistingEntries(m_constantRegisters, alternative->m_constantRegisters);
+ replaceExistingEntries(m_functionDecls, alternative->m_functionDecls);
+ replaceExistingEntries(m_functionExprs, alternative->m_functionExprs);
+ if (!!m_rareData && !!alternative->m_rareData)
+ replaceExistingEntries(m_rareData->m_constantBuffers, alternative->m_rareData->m_constantBuffers);
+}
+
+void CodeBlock::copyPostParseDataFromAlternative()
+{
+ copyPostParseDataFrom(m_alternative.get());
+}
+