void VM::throwException(ExecState* exec, Exception* exception) { if (Options::breakOnThrow()) { dataLog("In call frame ", RawPointer(exec), " for code block ", *exec->codeBlock(), "\n"); CRASH(); } ASSERT(exec == topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec()); interpreter->notifyDebuggerOfExceptionToBeThrown(exec, exception); setException(exception); }
static const char *symbolLookupCallback( void* opaque, uint64_t referenceValue, uint64_t* referenceType, uint64_t referencePC, const char** referenceName) { // Set this if you want to debug an unexpected reference type. Currently we only encounter these // if we try to disassemble garbage, since our code generator never uses them. These include things // like PC-relative references. static const bool crashOnUnexpected = false; char* symbolString = static_cast<char*>(opaque); switch (*referenceType) { case LLVMDisassembler_ReferenceType_InOut_None: return 0; case LLVMDisassembler_ReferenceType_In_Branch: *referenceName = 0; *referenceType = LLVMDisassembler_ReferenceType_InOut_None; snprintf( symbolString, symbolStringSize, "0x%lx", static_cast<unsigned long>(referenceValue)); return symbolString; default: if (crashOnUnexpected) { dataLog("referenceValue = ", referenceValue, "\n"); dataLog("referenceType = ", RawPointer(referenceType), ", *referenceType = ", *referenceType, "\n"); dataLog("referencePC = ", referencePC, "\n"); dataLog("referenceName = ", RawPointer(referenceName), "\n"); RELEASE_ASSERT_NOT_REACHED(); } *referenceName = "unimplemented reference type!"; *referenceType = LLVMDisassembler_ReferenceType_InOut_None; snprintf( symbolString, symbolStringSize, "unimplemented:0x%lx", static_cast<unsigned long>(referenceValue)); return symbolString; } }
void Worklist::enqueue(PassRefPtr<Plan> passedPlan) { RefPtr<Plan> plan = passedPlan; MutexLocker locker(m_lock); if (Options::verboseCompilationQueue()) { dump(locker, WTF::dataFile()); dataLog(": Enqueueing plan to optimize ", plan->key(), "\n"); } ASSERT(m_plans.find(plan->key()) == m_plans.end()); m_plans.add(plan->key(), plan); m_queue.append(plan); m_planEnqueued.signal(); }
void JITToDFGDeferredCompilationCallback::compilationDidComplete( CodeBlock* codeBlock, CompilationResult result) { ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT); if (Options::verboseOSR()) dataLog("Optimizing compilation of ", *codeBlock, " result: ", result, "\n"); if (result == CompilationSuccessful) codeBlock->install(); codeBlock->alternative()->setOptimizationThresholdBasedOnCompilationResult(result); }
void coalesce() { unsigned moveIndex = m_worklistMoves.takeLastMove(); const MoveOperands& moveOperands = m_coalescingCandidates[moveIndex]; IndexType u = getAlias(moveOperands.srcIndex); IndexType v = getAlias(moveOperands.dstIndex); if (isPrecolored(v)) std::swap(u, v); if (traceDebug) dataLog("Coalescing move at index", moveIndex, " u = ", u, " v = ", v, "\n"); if (u == v) { addWorkList(u); if (traceDebug) dataLog(" Coalesced\n"); } else if (isPrecolored(v) || m_interferenceEdges.contains(InterferenceEdge(u, v))) { addWorkList(u); addWorkList(v); if (traceDebug) dataLog(" Constrained\n"); } else if (canBeSafelyCoalesced(u, v)) { combine(u, v); addWorkList(u); m_hasCoalescedNonTrivialMove = true; if (traceDebug) dataLog(" Safe Coalescing\n"); } else { m_activeMoves.quickSet(moveIndex); if (traceDebug) dataLog(" Failed coalescing, added to active moves.\n"); } }
void CallLinkInfo::visitWeak(RepatchBuffer& repatchBuffer) { auto handleSpecificCallee = [&] (JSFunction* callee) { if (Heap::isMarked(callee->executable())) m_hasSeenClosure = true; else m_clearedByGC = true; }; if (isLinked()) { if (stub()) { if (!stub()->visitWeak(repatchBuffer)) { if (Options::verboseOSR()) { dataLog( "Clearing closure call from ", *repatchBuffer.codeBlock(), " to ", listDump(stub()->variants()), ", stub routine ", RawPointer(stub()), ".\n"); } unlink(repatchBuffer); m_clearedByGC = true; } } else if (!Heap::isMarked(m_callee.get())) { if (Options::verboseOSR()) { dataLog( "Clearing call from ", *repatchBuffer.codeBlock(), " to ", RawPointer(m_callee.get()), " (", m_callee.get()->executable()->hashFor(specializationKind()), ").\n"); } handleSpecificCallee(m_callee.get()); unlink(repatchBuffer); } } if (haveLastSeenCallee() && !Heap::isMarked(lastSeenCallee())) { handleSpecificCallee(lastSeenCallee()); clearLastSeenCallee(); } }
int main(int argc, char** argv) { WTF::initializeThreading(); if (argc != 8 || !parseValue(argv[2], &numThreadGroups) || !parseValue(argv[3], &numThreadsPerGroup) || !parseValue(argv[4], &workPerCriticalSection) || !parseValue(argv[5], &workBetweenCriticalSections) || !parseValue(argv[6], &toyLockSpinLimit) || sscanf(argv[7], "%lf", &secondsPerTest) != 1) usage(); if (rangeVariable) { dataLog("Running with rangeMin = ", rangeMin, ", rangeMax = ", rangeMax, ", rangeStep = ", rangeStep, "\n"); for (unsigned value = rangeMin; value <= rangeMax; value += rangeStep) { dataLog("Running with value = ", value, "\n"); *rangeVariable = value; runEverything<Benchmark>(argv[1]); } } else runEverything<Benchmark>(argv[1]); for (auto& entry : results) { printf("%s = {", entry.key.data()); bool first = true; for (double value : entry.value) { if (first) first = false; else printf(", "); printf("%.3lf", value); } printf("};\n"); } return 0; }
JSValue ModuleLoaderObject::evaluate(ExecState* exec, JSValue key, JSValue moduleRecordValue) { if (Options::dumpModuleLoadingState()) dataLog("Loader [evaluate] ", printableModuleKey(exec, key), "\n"); JSGlobalObject* globalObject = exec->lexicalGlobalObject(); if (globalObject->globalObjectMethodTable()->moduleLoaderEvaluate) return globalObject->globalObjectMethodTable()->moduleLoaderEvaluate(globalObject, exec, key, moduleRecordValue); JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(moduleRecordValue); if (!moduleRecord) return jsUndefined(); return moduleRecord->evaluate(exec); }
void Heap::visitException(HeapRootVisitor& visitor) { GCPHASE(MarkingException); if (!m_vm->exception() && !m_vm->lastException()) return; visitor.visit(m_vm->addressOfException()); visitor.visit(m_vm->addressOfLastException()); if (Options::logGC() == GCLogging::Verbose) dataLog("Exceptions:\n", m_slotVisitor); m_slotVisitor.donateAndDrain(); }
void BlockDirectory::stopAllocatingForGood() { if (false) dataLog(RawPointer(this), ": BlockDirectory::stopAllocatingForGood!\n"); m_localAllocators.forEach( [&] (LocalAllocator* allocator) { allocator->stopAllocatingForGood(); }); auto locker = holdLock(m_localAllocatorsLock); while (!m_localAllocators.isEmpty()) m_localAllocators.begin()->remove(); }
void BytecodeLivenessAnalysis::dumpResults() { CodeBlock* codeBlock = m_graph.codeBlock(); dataLog("\nDumping bytecode liveness for ", *codeBlock, ":\n"); Interpreter* interpreter = codeBlock->vm()->interpreter; Instruction* instructionsBegin = codeBlock->instructions().begin(); unsigned i = 0; for (BytecodeBasicBlock* block : m_graph) { dataLogF("\nBytecode basic block %u: %p (offset: %u, length: %u)\n", i++, block, block->leaderOffset(), block->totalLength()); dataLogF("Successors: "); for (unsigned j = 0; j < block->successors().size(); j++) { BytecodeBasicBlock* successor = block->successors()[j]; dataLogF("%p ", successor); } dataLogF("\n"); if (block->isEntryBlock()) { dataLogF("Entry block %p\n", block); continue; } if (block->isExitBlock()) { dataLogF("Exit block: %p\n", block); continue; } for (unsigned bytecodeOffset = block->leaderOffset(); bytecodeOffset < block->leaderOffset() + block->totalLength();) { const Instruction* currentInstruction = &instructionsBegin[bytecodeOffset]; dataLogF("Live variables: "); FastBitVector liveBefore = getLivenessInfoAtBytecodeOffset(bytecodeOffset); for (unsigned j = 0; j < liveBefore.numBits(); j++) { if (liveBefore.get(j)) dataLogF("%u ", j); } dataLogF("\n"); codeBlock->dumpBytecode(WTF::dataFile(), codeBlock->globalObject()->globalExec(), instructionsBegin, currentInstruction); OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode); unsigned opcodeLength = opcodeLengths[opcodeID]; bytecodeOffset += opcodeLength; } dataLogF("Live variables: "); FastBitVector liveAfter = block->out(); for (unsigned j = 0; j < liveAfter.numBits(); j++) { if (liveAfter.get(j)) dataLogF("%u ", j); } dataLogF("\n"); } }
void MarkedAllocator::stopAllocating() { if (false) dataLog(RawPointer(this), ": MarkedAllocator::stopAllocating!\n"); ASSERT(!m_lastActiveBlock); if (!m_currentBlock) { ASSERT(!m_freeList); return; } m_currentBlock->stopAllocating(m_freeList); m_lastActiveBlock = m_currentBlock; m_currentBlock = 0; m_freeList = FreeList(); }
void ToFTLDeferredCompilationCallback::compilationDidComplete( CodeBlock* codeBlock, CompilationResult result) { if (Options::verboseOSR()) { dataLog( "Optimizing compilation of ", *codeBlock, " (for ", *m_dfgCodeBlock, ") result: ", result, "\n"); } if (result == CompilationSuccessful) codeBlock->install(); m_dfgCodeBlock->jitCode()->dfg()->setOptimizationThresholdBasedOnCompilationResult( m_dfgCodeBlock.get(), result); }
void UnlinkedCodeBlock::dumpExpressionRangeInfo() { Vector<ExpressionRangeInfo>& expressionInfo = m_expressionInfo; size_t size = m_expressionInfo.size(); dataLogF("UnlinkedCodeBlock %p expressionRangeInfo[%zu] {\n", this, size); for (size_t i = 0; i < size; i++) { ExpressionRangeInfo& info = expressionInfo[i]; unsigned line; unsigned column; getLineAndColumn(info, line, column); dumpLineColumnEntry(i, instructions(), info.instructionOffset, line, column); } dataLog("}\n"); }
void ArrayProfile::computeUpdatedPrediction(CodeBlock* codeBlock, OperationInProgress operation) { const bool verbose = false; if (m_lastSeenStructure) { m_observedArrayModes |= arrayModeFromStructure(m_lastSeenStructure); m_mayInterceptIndexedAccesses |= m_lastSeenStructure->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero(); if (!codeBlock->globalObject()->isOriginalArrayStructure(m_lastSeenStructure)) m_usesOriginalArrayStructures = false; if (!structureIsPolymorphic()) { if (!m_expectedStructure) m_expectedStructure = m_lastSeenStructure; else if (m_expectedStructure != m_lastSeenStructure) { if (verbose) dataLog(*codeBlock, " bc#", m_bytecodeOffset, ": making structure polymorphic because ", RawPointer(m_expectedStructure), " (", m_expectedStructure->classInfo()->className, ") != ", RawPointer(m_lastSeenStructure), " (", m_lastSeenStructure->classInfo()->className, ")\n"); m_expectedStructure = polymorphicStructure(); } } m_lastSeenStructure = 0; } if (hasTwoOrMoreBitsSet(m_observedArrayModes)) { if (verbose) dataLog(*codeBlock, " bc#", m_bytecodeOffset, ": making structure polymorphic because two or more bits are set in m_observedArrayModes\n"); m_expectedStructure = polymorphicStructure(); } if (operation == Collection && expectedStructure() && !Heap::isMarked(m_expectedStructure)) { if (verbose) dataLog(*codeBlock, " bc#", m_bytecodeOffset, ": making structure during GC\n"); m_expectedStructure = polymorphicStructure(); } }
void Graph::predictArgumentTypes() { ASSERT(m_codeBlock->numParameters() >= 1); for (size_t arg = 0; arg < static_cast<size_t>(m_codeBlock->numParameters()); ++arg) { ValueProfile* profile = m_profiledBlock->valueProfileForArgument(arg); if (!profile) continue; at(m_arguments[arg]).variableAccessData()->predict(profile->computeUpdatedPrediction()); #if DFG_ENABLE(DEBUG_VERBOSE) dataLog("Argument [%zu] prediction: %s\n", arg, speculationToString(at(m_arguments[arg]).variableAccessData()->prediction())); #endif } }
EncodedJSValue JSC_HOST_CALL moduleLoaderObjectModuleDeclarationInstantiation(ExecState* exec) { JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(exec->argument(0)); if (!moduleRecord) return JSValue::encode(jsUndefined()); if (Options::dumpModuleLoadingState()) dataLog("Loader [link] ", moduleRecord->moduleKey(), "\n"); moduleRecord->link(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); return JSValue::encode(jsUndefined()); }
EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeModuleDeclarationInstantiation(ExecState* exec) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(vm, exec->argument(0)); if (!moduleRecord) return JSValue::encode(jsUndefined()); if (Options::dumpModuleLoadingState()) dataLog("Loader [link] ", moduleRecord->moduleKey(), "\n"); moduleRecord->link(exec); RETURN_IF_EXCEPTION(scope, encodedJSValue()); return JSValue::encode(jsUndefined()); }
void performBlockCFA(BlockIndex blockIndex) { BasicBlock* block = m_graph.m_blocks[blockIndex].get(); if (!block) return; if (!block->cfaShouldRevisit) return; #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" Block #%u (bc#%u):\n", blockIndex, block->bytecodeBegin); #endif m_state.beginBasicBlock(block); #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" head vars: "); dumpOperands(block->valuesAtHead, WTF::dataFile()); dataLog("\n"); #endif for (unsigned i = 0; i < block->size(); ++i) { NodeIndex nodeIndex = block->at(i); if (!m_graph[nodeIndex].shouldGenerate()) continue; #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" %s @%u: ", Graph::opName(m_graph[nodeIndex].op()), nodeIndex); m_state.dump(WTF::dataFile()); dataLog("\n"); #endif if (!m_state.execute(i)) break; } #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" tail regs: "); m_state.dump(WTF::dataFile()); dataLog("\n"); #endif m_changed |= m_state.endBasicBlock(AbstractState::MergeToSuccessors); #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" tail vars: "); dumpOperands(block->valuesAtTail, WTF::dataFile()); dataLog("\n"); #endif }
void ToFTLForOSREntryDeferredCompilationCallback::compilationDidComplete( CodeBlock* codeBlock, CompilationResult result) { if (Options::verboseOSR()) { dataLog( "Optimizing compilation of ", *codeBlock, " (for ", *m_dfgCodeBlock, ") result: ", result, "\n"); } if (result == CompilationSuccessful) m_dfgCodeBlock->jitCode()->dfg()->osrEntryBlock = codeBlock; // FIXME: if we failed, we might want to just turn off OSR entry rather than // totally turning off tier-up. m_dfgCodeBlock->jitCode()->dfg()->setOptimizationThresholdBasedOnCompilationResult( m_dfgCodeBlock.get(), result); }
void CodeBlockSet::traceMarked(SlotVisitor& visitor) { if (verbose) dataLog("Tracing ", m_currentlyExecuting.size(), " code blocks.\n"); // We strongly visit the currently executing set because jettisoning code // is not valuable once it's on the stack. We're past the point where // jettisoning would avoid the cost of OSR exit. for (const RefPtr<CodeBlock>& codeBlock : m_currentlyExecuting) codeBlock->visitStrongly(visitor); // We strongly visit the remembered set because jettisoning old code during // Eden GC is unsound. There might be an old object with a strong reference // to the code. for (const RefPtr<CodeBlock>& codeBlock : m_remembered) codeBlock->visitStrongly(visitor); }
JITCode::~JITCode() { if (FTL::shouldDumpDisassembly()) { dataLog("Destroying FTL JIT code at "); CommaPrinter comma; #if FTL_USES_B3 dataLog(comma, m_b3Code); dataLog(comma, m_arityCheckEntrypoint); #else for (auto& handle : m_handles) dataLog(comma, pointerDump(handle.get())); dataLog(comma, pointerDump(m_arityCheckEntrypoint.executableMemory())); dataLog(comma, pointerDump(m_exitThunks.executableMemory())); dataLog("\n"); #endif } }
JSInternalPromise* ModuleLoaderObject::fetch(ExecState* exec, JSValue key) { if (Options::dumpModuleLoadingState()) dataLog("Loader [fetch] ", printableModuleKey(exec, key), "\n"); JSGlobalObject* globalObject = exec->lexicalGlobalObject(); if (globalObject->globalObjectMethodTable()->moduleLoaderFetch) return globalObject->globalObjectMethodTable()->moduleLoaderFetch(globalObject, exec, key); JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::create(exec, globalObject); String moduleKey = key.toString(exec)->value(exec); if (exec->hadException()) { JSValue exception = exec->exception()->value(); exec->clearException(); deferred->reject(exec, exception); return deferred->promise(); } deferred->reject(exec, createError(exec, makeString("Could not open the module '", moduleKey, "'."))); return deferred->promise(); }
void ProfiledCodeBlockJettisoningWatchpoint::fireInternal() { if (DFG::shouldShowDisassembly()) { dataLog( "Firing profiled watchpoint ", RawPointer(this), " on ", *m_codeBlock, " due to ", m_exitKind, " at ", m_codeOrigin, "\n"); } baselineCodeBlockForOriginAndBaselineCodeBlock( m_codeOrigin, m_codeBlock->baselineVersion())->addFrequentExitSite( DFG::FrequentExitSite(m_codeOrigin.bytecodeIndex, m_exitKind)); #if ENABLE(JIT) m_codeBlock->jettison(CountReoptimization); #endif if (isOnList()) remove(); }
bool Plan::parseAndValidateModule() { MonotonicTime startTime; if (verbose || Options::reportCompileTimes()) startTime = MonotonicTime::now(); { ModuleParser moduleParser(m_vm, m_source, m_sourceLength); auto parseResult = moduleParser.parse(); if (!parseResult) { m_errorMessage = parseResult.error(); return false; } m_moduleInformation = WTFMove(parseResult->module); m_functionLocationInBinary = WTFMove(parseResult->functionLocationInBinary); m_moduleSignatureIndicesToUniquedSignatureIndices = WTFMove(parseResult->moduleSignatureIndicesToUniquedSignatureIndices); } for (unsigned functionIndex = 0; functionIndex < m_functionLocationInBinary.size(); ++functionIndex) { if (verbose) dataLogLn("Processing function starting at: ", m_functionLocationInBinary[functionIndex].start, " and ending at: ", m_functionLocationInBinary[functionIndex].end); const uint8_t* functionStart = m_source + m_functionLocationInBinary[functionIndex].start; size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start; ASSERT(functionLength <= m_sourceLength); SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex]; const Signature* signature = SignatureInformation::get(m_vm, signatureIndex); auto validationResult = validateFunction(m_vm, functionStart, functionLength, signature, *m_moduleInformation, m_moduleSignatureIndicesToUniquedSignatureIndices); if (!validationResult) { if (verbose) { for (unsigned i = 0; i < functionLength; ++i) dataLog(RawPointer(reinterpret_cast<void*>(functionStart[i])), ", "); dataLogLn(); } m_errorMessage = makeString(validationResult.error(), ", in function at index ", String::number(functionIndex)); // FIXME make this an Expected. return false; } } if (verbose || Options::reportCompileTimes()) dataLogLn("Took ", (MonotonicTime::now() - startTime).microseconds(), " us to validate module"); return true; }
void performBlockCFA(BasicBlock* block) { if (!block) return; if (!block->cfaShouldRevisit) return; if (m_verbose) dataLog(" Block ", *block, ":\n"); m_state.beginBasicBlock(block); if (m_verbose) { dataLog(" head vars: ", block->valuesAtHead, "\n"); if (m_graph.m_form == SSA) dataLog(" head regs: ", nodeValuePairListDump(block->ssa->valuesAtHead), "\n"); } for (unsigned i = 0; i < block->size(); ++i) { if (m_verbose) { Node* node = block->at(i); dataLogF(" %s @%u: ", Graph::opName(node->op()), node->index()); if (!safeToExecute(m_state, m_graph, node)) dataLog("(UNSAFE) "); dataLog(m_state.variables(), " ", m_interpreter); dataLogF("\n"); } if (!m_interpreter.execute(i)) { if (m_verbose) dataLogF(" Expect OSR exit.\n"); break; } } if (m_verbose) { dataLogF(" tail regs: "); m_interpreter.dump(WTF::dataFile()); dataLogF("\n"); } m_changed |= m_state.endBasicBlock(); if (m_verbose) { dataLog(" tail vars: ", block->valuesAtTail, "\n"); if (m_graph.m_form == SSA) dataLog(" head regs: ", nodeValuePairListDump(block->ssa->valuesAtTail), "\n"); } }
void TypeProfilerLog::processLogEntries(const String& reason) { double before = 0; if (verbose) { dataLog("Process caller:'", reason, "'"); before = currentTimeMS(); } LogEntry* entry = m_logStartPtr; HashMap<Structure*, RefPtr<StructureShape>> seenShapes; while (entry != m_currentLogEntryPtr) { StructureID id = entry->structureID; RefPtr<StructureShape> shape; JSValue value = entry->value; Structure* structure = nullptr; if (id) { structure = Heap::heap(value.asCell())->structureIDTable().get(id); auto iter = seenShapes.find(structure); if (iter == seenShapes.end()) { shape = structure->toStructureShape(value); seenShapes.set(structure, shape); } else shape = iter->value; } RuntimeType type = runtimeTypeForValue(value); TypeLocation* location = entry->location; location->m_lastSeenType = type; if (location->m_globalTypeSet) location->m_globalTypeSet->addTypeInformation(type, shape, structure); location->m_instructionTypeSet->addTypeInformation(type, shape, structure); entry++; } m_currentLogEntryPtr = m_logStartPtr; if (verbose) { double after = currentTimeMS(); dataLogF(" Processing the log took: '%f' ms\n", after - before); } }
void AdaptiveStructureWatchpoint::fireInternal(const FireDetail& detail) { if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) { install(); return; } if (DFG::shouldDumpDisassembly()) { dataLog( "Firing watchpoint ", RawPointer(this), " (", m_key, ") on ", *m_codeBlock, "\n"); } StringPrintStream out; out.print("Adaptation of ", m_key, " failed: ", detail); StringFireDetail stringDetail(out.toCString().data()); m_codeBlock->jettison( Profiler::JettisonDueToUnprofiledWatchpoint, CountReoptimization, &stringDetail); }
void VM::verifyExceptionCheckNeedIsSatisfied(unsigned recursionDepth, ExceptionEventLocation& location) { if (!Options::validateExceptionChecks()) return; if (UNLIKELY(m_needExceptionCheck)) { auto throwDepth = m_simulatedThrowPointRecursionDepth; auto& throwLocation = m_simulatedThrowPointLocation; dataLog( "ERROR: Unchecked JS exception:\n" " This scope can throw a JS exception: ", throwLocation, "\n" " (ExceptionScope::m_recursionDepth was ", throwDepth, ")\n" " But the exception was unchecked as of this scope: ", location, "\n" " (ExceptionScope::m_recursionDepth was ", recursionDepth, ")\n" "\n"); RELEASE_ASSERT(!m_needExceptionCheck); } }
bool run() { ASSERT(m_graph.m_form == ThreadedCPS); ASSERT(m_graph.m_unificationState == GloballyUnified); ASSERT(codeBlock()->numParameters() >= 1); for (size_t arg = 0; arg < static_cast<size_t>(codeBlock()->numParameters()); ++arg) { ValueProfile* profile = profiledBlock()->valueProfileForArgument(arg); if (!profile) continue; m_graph.m_arguments[arg]->variableAccessData()->predict(profile->computeUpdatedPrediction()); #if DFG_ENABLE(DEBUG_VERBOSE) dataLog( "Argument [", arg, "] prediction: ", SpeculationDump(m_graph.m_arguments[arg]->variableAccessData()->prediction()), "\n"); #endif } for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) { BasicBlock* block = m_graph.m_blocks[blockIndex].get(); if (!block) continue; if (!block->isOSRTarget) continue; if (block->bytecodeBegin != m_graph.m_osrEntryBytecodeIndex) continue; for (size_t i = 0; i < m_graph.m_mustHandleValues.size(); ++i) { Node* node = block->variablesAtHead.operand( m_graph.m_mustHandleValues.operandForIndex(i)); if (!node) continue; ASSERT(node->hasLocal()); node->variableAccessData()->predict( speculationFromValue(m_graph.m_mustHandleValues[i])); } } return true; }