123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- // Copyright (C) 2012 Sony Computer Entertainment Inc.
- // All Rights Reserved.
- #include "config.h"
- #if ENABLE(JIT) && ENABLE(DETACHED_JIT) && !BUILDING_DETACHED_JIT
- #include "JIT.h"
- #include "JSCBridge.h"
- #include "JSCBridgeToll.h"
- #include <wtf/OwnPtr.h>
- namespace JSC {
- void ctiPatchCallByReturnAddress(CodeBlock* codeBlock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(newCalleeFunction.executableAddress()));
- bridge->requestCompilerTask(JSCBridge::e_ctiPatchCallReturnAddrCodePtr);
- }
- void ctiPatchCallByReturnAddress(CodeBlock* codeBlock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(newCalleeFunction.executableAddress()));
- bridge->requestCompilerTask(JSCBridge::e_ctiPatchCallReturnAddrFunctionPtr);
- }
- JITCode JIT::compile(VM* vm, CodeBlock* codeBlock, JITCompilationEffort effort, CodePtr* functionEntryArityCheck)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- CodePtr * sharedFunctionArityCheck(functionEntryArityCheck ? sharedNew<CodePtr>(*functionEntryArityCheck) : NULL);
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(static_cast <uintptr_t>(effort));
- payload->sendArgument(reinterpret_cast<uintptr_t>(sharedFunctionArityCheck));
- OwnPtr<JSCBridgeToll> toll(adoptPtr(bridge->createToll(payload.get())));
- toll->prepare(vm);
- toll->prepare(codeBlock);
- JITCode * sharedCode(reinterpret_cast<JITCode *>(bridge->requestCompilerTask(JSCBridge::e_JIT_compile)));
- JITCode result(*sharedCode);
- sharedDelete<JITCode>(sharedCode);
- if (functionEntryArityCheck) {
- *functionEntryArityCheck = *sharedFunctionArityCheck;
- sharedDelete<CodePtr>(sharedFunctionArityCheck);
- }
- return result;
- }
- void JIT::compileClosureCall(VM* vm, CallLinkInfo* callLinkInfo, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- MacroAssemblerCodePtr * const sharedCode(sharedNew<MacroAssemblerCodePtr>(codePtr));
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callLinkInfo));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callerCodeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(calleeCodeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(expectedStructure));
- payload->sendArgument(reinterpret_cast<uintptr_t>(expectedExecutable));
- payload->sendArgument(reinterpret_cast<uintptr_t>(sharedCode));
- bridge->requestCompilerTask(JSCBridge::e_JIT_compileClosureCall);
- sharedDelete<MacroAssemblerCodePtr>(sharedCode);
- }
- JIT::CodeRef JIT::compileCTINativeCall(VM* vm, NativeFunction func)
- {
- if (!vm->canUseJIT()) {
- #if ENABLE(LLINT)
- return CodeRef::createLLIntCodeRef(llint_native_call_trampoline);
- #else
- return CodeRef();
- #endif
- }
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(func));
- MacroAssemblerCodeRef * sharedCodeRef(reinterpret_cast<MacroAssemblerCodeRef *>(bridge->requestCompilerTask(JSCBridge::e_JIT_compileCTINativeCall)));
- MacroAssemblerCodeRef codeRef(*sharedCodeRef);
- sharedDelete<MacroAssemblerCodeRef>(sharedCodeRef);
- return codeRef;
- }
- }
- void JIT::compileGetByIdChain(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callFrame));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
- payload->sendArgument(reinterpret_cast<uintptr_t>(structure));
- payload->sendArgument(reinterpret_cast<uintptr_t>(chain));
- payload->sendArgument( static_cast<uintptr_t>(count));
- payload->sendArgument(reinterpret_cast<uintptr_t>(&ident)); // ident is only used as a TrustedImmPtr so it's ok for it to be not shared allocated
- payload->sendPOD(&slot); // slot is a const so it's safe to assume slot will not be modifed so no need to expect a return value from the compiler
- payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
- payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
- bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByIdChain);
- }
- void JIT::compileGetByIdChainList(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callFrame));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
- payload->sendArgument(reinterpret_cast<uintptr_t>(prototypeStructureList));
- payload->sendArgument( static_cast<uintptr_t>(currentIndex));
- payload->sendArgument(reinterpret_cast<uintptr_t>(structure));
- payload->sendArgument(reinterpret_cast<uintptr_t>(chain));
- payload->sendArgument( static_cast<uintptr_t>(count));
- payload->sendArgument(reinterpret_cast<uintptr_t>(&ident)); // ident is only used as a TrustedImmPtr so it's ok for it to be not shared allocated
- payload->sendPOD(&slot); // slot is a const so it's safe to assume slot will not be modifed so no need to expect a return value from the compiler
- payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
- bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByIdChainList);
- }
- void JIT::compileGetByIdProto(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callFrame));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
- payload->sendArgument(reinterpret_cast<uintptr_t>(structure));
- payload->sendArgument(reinterpret_cast<uintptr_t>(prototypeStructure));
- payload->sendArgument(reinterpret_cast<uintptr_t>(&ident)); // ident is only used as a TrustedImmPtr so it's ok for it to be not shared allocated
- payload->sendPOD(&slot); // slot is a const so it's safe to assume slot will not be modifed so no need to expect a return value from the compiler
- payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
- payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
- bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByIdProto);
- }
- void JIT::compileGetByIdProtoList(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callFrame));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
- payload->sendArgument(reinterpret_cast<uintptr_t>(prototypeStructureList));
- payload->sendArgument( static_cast<uintptr_t>(currentIndex));
- payload->sendArgument(reinterpret_cast<uintptr_t>(structure));
- payload->sendArgument(reinterpret_cast<uintptr_t>(prototypeStructure));
- payload->sendArgument(reinterpret_cast<uintptr_t>(&ident)); // ident is only used as a TrustedImmPtr so it's ok for it to be not shared allocated
- payload->sendPOD(&slot); // slot is a const so it's safe to assume slot will not be modifed so no need to expect a return value from the compiler
- payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
- bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByIdProtoList);
- }
- void JIT::compileGetByIdSelfList(VM* vm, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
- payload->sendArgument(reinterpret_cast<uintptr_t>(polymorphicStructures));
- payload->sendArgument( static_cast<uintptr_t>(currentIndex));
- payload->sendArgument(reinterpret_cast<uintptr_t>(structure));
- payload->sendArgument(reinterpret_cast<uintptr_t>(&ident)); // ident is only used as a TrustedImmPtr so it's ok for it to be not shared allocated
- payload->sendPOD(&slot); // slot is a const so it's safe to assume slot will not be modifed so no need to expect a return value from the compiler
- payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
- bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByIdSelfList);
- }
- void JIT::compileGetByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(byValInfo));
- payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
- payload->sendArgument( static_cast<uintptr_t>(arrayMode));
- bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByVal);
- }
- void JIT::compilePatchGetArrayLength(VM* vm, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
- bridge->requestCompilerTask(JSCBridge::e_JIT_compilePatchGetArrayLength);
- }
- void JIT::compilePutByIdTransition(VM* vm, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, PropertyOffset cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
- payload->sendArgument(reinterpret_cast<uintptr_t>(oldStructure));
- payload->sendArgument(reinterpret_cast<uintptr_t>(newStructure));
- payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
- payload->sendArgument(reinterpret_cast<uintptr_t>(chain));
- payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
- payload->sendArgument( static_cast<uintptr_t>(direct));
- OwnPtr<JSCBridgeToll> toll(adoptPtr(bridge->createToll(payload.get())));
- toll->prepare(vm);
- toll->prepare(codeBlock);
- bridge->requestCompilerTask(JSCBridge::e_JIT_compilePutByIdTransition);
- }
- void JIT::compilePutByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(byValInfo));
- payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
- payload->sendArgument( static_cast<uintptr_t>(arrayMode));
- bridge->requestCompilerTask(JSCBridge::e_JIT_compilePutByVal);
- }
- void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, MacroAssemblerCodePtr code, CallLinkInfo* callLinkInfo, VM* vm, CodeSpecializationKind kind)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- MacroAssemblerCodePtr * const sharedCode(sharedNew<MacroAssemblerCodePtr>(code));
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callee));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callerCodeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(calleeCodeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(sharedCode));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callLinkInfo));
- payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
- payload->sendArgument( static_cast<uintptr_t>(kind));
- bridge->requestCompilerTask(JSCBridge::e_JIT_linkFor);
- sharedDelete<MacroAssemblerCodePtr>(sharedCode);
- }
- void JIT::linkSlowCall(CodeBlock* callerCodeBlock, CallLinkInfo* callLinkInfo)
- {
- PROFILE_FUNCTION_CALL;
- JSCBridge * const bridge(JSCBridge::sharedInstance());
- OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callerCodeBlock));
- payload->sendArgument(reinterpret_cast<uintptr_t>(callLinkInfo));
- bridge->requestCompilerTask(JSCBridge::e_JIT_linkSlowCall);
- }
- } // namespace JSC
- #endif // #if ENABLE(JIT) && ENABLE(DETACHED_JIT) && !BUILDING_DETACHED_JIT
|