int SamplingProfiler::StackFrame::startLine() { if (frameType == FrameType::Unknown || frameType == FrameType::Host) return -1; RELEASE_ASSERT(frameType != FrameType::UnverifiedCallee); ExecutableBase* executable = u.verifiedExecutable; if (executable->isHostFunction()) return -1; return static_cast<ScriptExecutable*>(executable)->firstLine(); }
String SamplingProfiler::StackFrame::url() { if (frameType == FrameType::Unknown || frameType == FrameType::Host) return emptyString(); RELEASE_ASSERT(frameType != FrameType::UnverifiedCallee); ExecutableBase* executable = u.verifiedExecutable; if (executable->isHostFunction()) return emptyString(); String url = static_cast<ScriptExecutable*>(executable)->sourceURL(); if (url.isEmpty()) return static_cast<ScriptExecutable*>(executable)->source().provider()->sourceURL(); // Fall back to sourceURL directive. return url; }
void Heap::deleteAllCompiledCode() { // If JavaScript is running, it's not safe to delete code, since we'll end // up deleting code that is live on the stack. if (m_vm->entryScope) return; for (ExecutableBase* current = m_compiledCode.head(); current; current = current->next()) { if (!current->isFunctionExecutable()) continue; static_cast<FunctionExecutable*>(current)->clearCodeIfNotCompiling(); } m_codeBlocks.clearMarks(); m_codeBlocks.deleteUnmarkedAndUnreferenced(); }
void Heap::deleteAllCompiledCode() { // If JavaScript is running, it's not safe to delete code, since we'll end // up deleting code that is live on the stack. if (m_globalData->dynamicGlobalObject) return; for (ExecutableBase* current = m_compiledCode.head(); current; current = current->next()) { if (!current->isFunctionExecutable()) continue; static_cast<FunctionExecutable*>(current)->clearCodeIfNotCompiling(); } m_dfgCodeBlocks.clearMarks(); m_dfgCodeBlocks.deleteUnmarkedJettisonedCodeBlocks(); }
void Heap::deleteUnmarkedCompiledCode() { ExecutableBase* next; for (ExecutableBase* current = m_compiledCode.head(); current; current = next) { next = current->next(); if (isMarked(current)) continue; // We do this because executable memory is limited on some platforms and because // CodeBlock requires eager finalization. ExecutableBase::clearCodeVirtual(current); m_compiledCode.remove(current); } m_codeBlocks.deleteUnmarkedAndUnreferenced(); m_jitStubRoutines.deleteUnmarkedJettisonedStubRoutines(); }
EncodedJSValue JSC_HOST_CALL boundThisNoArgsFunctionCall(ExecState* exec) { JSBoundFunction* boundFunction = jsCast<JSBoundFunction*>(exec->jsCallee()); MarkedArgumentBuffer args; for (unsigned i = 0; i < exec->argumentCount(); ++i) args.append(exec->uncheckedArgument(i)); JSFunction* targetFunction = jsCast<JSFunction*>(boundFunction->targetFunction()); ExecutableBase* executable = targetFunction->executable(); if (executable->hasJITCodeForCall()) { // Force the executable to cache its arity entrypoint. executable->entrypointFor(CodeForCall, MustCheckArity); } CallData callData; CallType callType = getCallData(targetFunction, callData); ASSERT(callType != CallType::None); return JSValue::encode(call(exec, targetFunction, callType, callData, boundFunction->boundThis(), args)); }
inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (UNLIKELY(!calleeAsFunctionCell)) return handleHostCall(execCallee, calleeAsValue, kind); JSFunction* function = asFunction(calleeAsFunctionCell); execCallee->setScopeChain(function->scopeUnchecked()); ExecutableBase* executable = function->executable(); if (UNLIKELY(!executable->hasJITCodeFor(kind))) { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind); if (error) { exec->globalData().exception = error; return 0; } } return executable->generatedJITCodeWithArityCheckFor(kind).executableAddress(); }
String SamplingProfiler::StackFrame::displayNameForJSONTests() { if (frameType == FrameType::Unknown) return ASCIILiteral("(unknown)"); if (frameType == FrameType::Host) return ASCIILiteral("(host)"); RELEASE_ASSERT(frameType != FrameType::UnverifiedCallee); ExecutableBase* executable = u.verifiedExecutable; if (executable->isHostFunction()) return static_cast<NativeExecutable*>(executable)->name(); if (executable->isFunctionExecutable()) { String result = static_cast<FunctionExecutable*>(executable)->inferredName().string(); if (result.isEmpty()) return ASCIILiteral("(anonymous function)"); return result; } if (executable->isEvalExecutable()) return ASCIILiteral("(eval)"); if (executable->isProgramExecutable()) return ASCIILiteral("(program)"); if (executable->isModuleProgramExecutable()) return ASCIILiteral("(module)"); RELEASE_ASSERT_NOT_REACHED(); return String(); }
inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (!calleeAsFunctionCell) return handleHostCall(execCallee, calleeAsValue, kind); JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell); execCallee->setScopeChain(callee->scopeUnchecked()); ExecutableBase* executable = callee->executable(); MacroAssemblerCodePtr codePtr; CodeBlock* codeBlock = 0; if (executable->isHostFunction()) codePtr = executable->generatedJITCodeFor(kind).addressForCall(); else { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind); if (error) { globalData->exception = createStackOverflowError(exec); return 0; } codeBlock = &functionExecutable->generatedBytecodeFor(kind); if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())) codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind); else codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall(); } CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress); if (!callLinkInfo.seenOnce()) callLinkInfo.setSeen(); else dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind); return codePtr.executableAddress(); }
inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind) { ExecState* exec = execCallee->callerFrame(); VM* vm = &exec->vm(); NativeCallFrameTracer tracer(vm, exec); JSValue calleeAsValue = execCallee->calleeAsValue(); JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue); if (!calleeAsFunctionCell) return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind)); JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell); execCallee->setScope(callee->scopeUnchecked()); ExecutableBase* executable = callee->executable(); MacroAssemblerCodePtr codePtr; CodeBlock* codeBlock = 0; if (executable->isHostFunction()) codePtr = executable->generatedJITCodeFor(kind)->addressForCall(); else { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind); if (error) { vm->throwException(exec, createStackOverflowError(exec)); return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); } codeBlock = functionExecutable->codeBlockFor(kind); if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())) codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind); else codePtr = functionExecutable->generatedJITCodeFor(kind)->addressForCall(); } CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(execCallee->returnPC()); if (!callLinkInfo.seenOnce()) callLinkInfo.setSeen(); else linkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind); return reinterpret_cast<char*>(codePtr.executableAddress()); }
inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKind kind, JSCell*& calleeAsFunctionCell) { ExecState* exec = execCallee->callerFrame(); VM* vm = &exec->vm(); NativeCallFrameTracer tracer(vm, exec); JSValue calleeAsValue = execCallee->calleeAsValue(); calleeAsFunctionCell = getJSFunction(calleeAsValue); if (UNLIKELY(!calleeAsFunctionCell)) return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind)); JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell); execCallee->setScope(function->scopeUnchecked()); ExecutableBase* executable = function->executable(); if (UNLIKELY(!executable->hasJITCodeFor(kind))) { FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable); JSObject* error = functionExecutable->prepareForExecution(execCallee, function->scope(), kind); if (error) { exec->vm().throwException(execCallee, error); return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress()); } } return reinterpret_cast<char*>(executable->generatedJITCodeWithArityCheckFor(kind).executableAddress()); }