CCallHelpers::JumpList generateImpl(AccessGenerationState& state, const RegisterSet& usedRegistersBySnippet, CCallHelpers& jit, std::index_sequence<ArgumentsIndex...>) { CCallHelpers::JumpList exceptions; // We spill (1) the used registers by IC and (2) the used registers by Snippet. AccessGenerationState::SpillState spillState = state.preserveLiveRegistersToStackForCall(usedRegistersBySnippet); jit.store32( CCallHelpers::TrustedImm32(state.callSiteIndexForExceptionHandlingOrOriginal().bits()), CCallHelpers::tagFor(static_cast<VirtualRegister>(CallFrameSlot::argumentCount))); jit.makeSpaceOnStackForCCall(); jit.setupArguments<FunctionType>(std::get<ArgumentsIndex>(m_arguments)...); CCallHelpers::Call operationCall = jit.call(OperationPtrTag); auto function = m_function; jit.addLinkTask([=] (LinkBuffer& linkBuffer) { linkBuffer.link(operationCall, FunctionPtr<OperationPtrTag>(function)); }); jit.setupResults(m_result); jit.reclaimSpaceOnStackForCCall(); CCallHelpers::Jump noException = jit.emitExceptionCheck(state.m_vm, CCallHelpers::InvertedExceptionCheck); state.restoreLiveRegistersFromStackForCallWithThrownException(spillState); exceptions.append(jit.jump()); noException.link(&jit); RegisterSet dontRestore; dontRestore.set(m_result); state.restoreLiveRegistersFromStackForCall(spillState, dontRestore); return exceptions; }
Box<CCallHelpers::JumpList> ExceptionTarget::jumps(CCallHelpers& jit) { Box<CCallHelpers::JumpList> result = Box<CCallHelpers::JumpList>::create(); if (m_isDefaultHandler) { Box<CCallHelpers::Label> defaultHandler = m_defaultHandler; jit.addLinkTask( [=] (LinkBuffer& linkBuffer) { linkBuffer.link(*result, linkBuffer.locationOf(*defaultHandler)); }); } else { RefPtr<OSRExitHandle> handle = m_handle; jit.addLinkTask( [=] (LinkBuffer& linkBuffer) { linkBuffer.link(*result, linkBuffer.locationOf(handle->label)); }); } return result; }
void OSRExitHandle::emitExitThunk(State& state, CCallHelpers& jit) { Profiler::Compilation* compilation = state.graph.compilation(); CCallHelpers::Label myLabel = jit.label(); label = myLabel; jit.pushToSaveImmediateWithoutTouchingRegisters(CCallHelpers::TrustedImm32(index)); CCallHelpers::PatchableJump jump = jit.patchableJump(); RefPtr<OSRExitHandle> self = this; VM& vm = state.vm(); jit.addLinkTask( [self, jump, myLabel, compilation, &vm] (LinkBuffer& linkBuffer) { self->exit.m_patchableJump = CodeLocationJump<JSInternalPtrTag>(linkBuffer.locationOf<JSInternalPtrTag>(jump)); linkBuffer.link( jump.m_jump, CodeLocationLabel<JITThunkPtrTag>(vm.getCTIStub(osrExitGenerationThunkGenerator).code())); if (compilation) compilation->addOSRExitSite({ linkBuffer.locationOf<JSInternalPtrTag>(myLabel) }); }); }