diff options
Diffstat (limited to 'Source/JavaScriptCore/assembler/LinkBuffer.h')
-rw-r--r-- | Source/JavaScriptCore/assembler/LinkBuffer.h | 92 |
1 files changed, 55 insertions, 37 deletions
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.h b/Source/JavaScriptCore/assembler/LinkBuffer.h index 8d4ce521f..efb26f9ce 100644 --- a/Source/JavaScriptCore/assembler/LinkBuffer.h +++ b/Source/JavaScriptCore/assembler/LinkBuffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2010, 2012-2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,8 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LinkBuffer_h -#define LinkBuffer_h +#pragma once #if ENABLE(ASSEMBLER) @@ -43,6 +42,7 @@ namespace JSC { +class CodeBlock; class VM; // LinkBuffer: @@ -79,36 +79,33 @@ class LinkBuffer { #endif public: - LinkBuffer(VM& vm, MacroAssembler* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed) + LinkBuffer(VM& vm, MacroAssembler& macroAssembler, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed) : m_size(0) -#if ENABLE(BRANCH_COMPACTION) - , m_initialSize(0) -#endif , m_didAllocate(false) , m_code(0) - , m_assembler(masm) , m_vm(&vm) #ifndef NDEBUG , m_completed(false) #endif { - linkCode(ownerUID, effort); + linkCode(macroAssembler, ownerUID, effort); } - LinkBuffer(VM& vm, MacroAssembler* masm, void* code, size_t size) + LinkBuffer(MacroAssembler& macroAssembler, void* code, size_t size, JITCompilationEffort effort = JITCompilationMustSucceed, bool shouldPerformBranchCompaction = true) : m_size(size) -#if ENABLE(BRANCH_COMPACTION) - , m_initialSize(0) -#endif , m_didAllocate(false) , m_code(code) - , m_assembler(masm) - , m_vm(&vm) + , m_vm(0) #ifndef NDEBUG , m_completed(false) #endif { - linkCode(0, JITCompilationCanFail); +#if ENABLE(BRANCH_COMPACTION) + m_shouldPerformBranchCompaction = shouldPerformBranchCompaction; +#else + UNUSED_PARAM(shouldPerformBranchCompaction); +#endif + linkCode(macroAssembler, 0, effort); } ~LinkBuffer() @@ -145,10 +142,10 @@ public: MacroAssembler::linkJump(code(), jump, label); } - void link(JumpList list, CodeLocationLabel label) + void link(const JumpList& list, CodeLocationLabel label) { - for (unsigned i = 0; i < list.m_jumps.size(); ++i) - link(list.m_jumps[i], label); + for (const Jump& jump : list.jumps()) + link(jump, label); } void patch(DataLabelPtr label, void* value) @@ -164,6 +161,11 @@ public: } // These methods are used to obtain handles to allow the code to be relinked / repatched later. + + CodeLocationLabel entrypoint() + { + return CodeLocationLabel(code()); + } CodeLocationCall locationOf(Call call) { @@ -176,7 +178,8 @@ public: { ASSERT(call.isFlagSet(Call::Linkable)); ASSERT(call.isFlagSet(Call::Near)); - return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label))); + return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label)), + call.isFlagSet(Call::Tail) ? NearCallMode::Tail : NearCallMode::Regular); } CodeLocationLabel locationOf(PatchableJump jump) @@ -244,34 +247,44 @@ public: { return m_code; } + + size_t size() const { return m_size; } - size_t size() - { - return m_size; - } + bool wasAlreadyDisassembled() const { return m_alreadyDisassembled; } + void didAlreadyDisassemble() { m_alreadyDisassembled = true; } + + VM& vm() { return *m_vm; } private: +#if ENABLE(BRANCH_COMPACTION) + int executableOffsetFor(int location) + { + if (!location) + return 0; + return bitwise_cast<int32_t*>(m_assemblerStorage.buffer())[location / sizeof(int32_t) - 1]; + } +#endif + template <typename T> T applyOffset(T src) { #if ENABLE(BRANCH_COMPACTION) - src.m_offset -= m_assembler->executableOffsetFor(src.m_offset); + src.m_offset -= executableOffsetFor(src.m_offset); #endif return src; } - + // Keep this private! - the underlying code should only be obtained externally via finalizeCode(). void* code() { return m_code; } - void allocate(size_t initialSize, void* ownerUID, JITCompilationEffort); - void shrink(size_t newSize); + void allocate(MacroAssembler&, void* ownerUID, JITCompilationEffort); - JS_EXPORT_PRIVATE void linkCode(void* ownerUID, JITCompilationEffort); + JS_EXPORT_PRIVATE void linkCode(MacroAssembler&, void* ownerUID, JITCompilationEffort); #if ENABLE(BRANCH_COMPACTION) template <typename InstructionType> - void copyCompactAndLinkCode(void* ownerUID, JITCompilationEffort); + void copyCompactAndLinkCode(MacroAssembler&, void* ownerUID, JITCompilationEffort); #endif void performFinalization(); @@ -287,15 +300,17 @@ private: RefPtr<ExecutableMemoryHandle> m_executableMemory; size_t m_size; #if ENABLE(BRANCH_COMPACTION) - size_t m_initialSize; + AssemblerData m_assemblerStorage; + bool m_shouldPerformBranchCompaction { true }; #endif bool m_didAllocate; void* m_code; - MacroAssembler* m_assembler; VM* m_vm; #ifndef NDEBUG bool m_completed; #endif + bool m_alreadyDisassembled { false }; + Vector<RefPtr<SharedTask<void(LinkBuffer&)>>> m_linkTasks; }; #define FINALIZE_CODE_IF(condition, linkBufferReference, dataLogFArgumentsForHeading) \ @@ -303,6 +318,11 @@ private: ? ((linkBufferReference).finalizeCodeWithDisassembly dataLogFArgumentsForHeading) \ : (linkBufferReference).finalizeCodeWithoutDisassembly()) +bool shouldDumpDisassemblyFor(CodeBlock*); + +#define FINALIZE_CODE_FOR(codeBlock, linkBufferReference, dataLogFArgumentsForHeading) \ + FINALIZE_CODE_IF(shouldDumpDisassemblyFor(codeBlock) || Options::asyncDisassembly(), linkBufferReference, dataLogFArgumentsForHeading) + // Use this to finalize code, like so: // // CodeRef code = FINALIZE_CODE(linkBuffer, ("my super thingy number %d", number)); @@ -316,17 +336,15 @@ private: // // ... and so on. // -// Note that the dataLogFArgumentsForHeading are only evaluated when showDisassembly +// Note that the dataLogFArgumentsForHeading are only evaluated when dumpDisassembly // is true, so you can hide expensive disassembly-only computations inside there. #define FINALIZE_CODE(linkBufferReference, dataLogFArgumentsForHeading) \ - FINALIZE_CODE_IF(JSC::Options::showDisassembly(), linkBufferReference, dataLogFArgumentsForHeading) + FINALIZE_CODE_IF(JSC::Options::asyncDisassembly() || JSC::Options::dumpDisassembly(), linkBufferReference, dataLogFArgumentsForHeading) #define FINALIZE_DFG_CODE(linkBufferReference, dataLogFArgumentsForHeading) \ - FINALIZE_CODE_IF((JSC::Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, dataLogFArgumentsForHeading) + FINALIZE_CODE_IF(JSC::Options::asyncDisassembly() || JSC::Options::dumpDisassembly() || Options::dumpDFGDisassembly(), linkBufferReference, dataLogFArgumentsForHeading) } // namespace JSC #endif // ENABLE(ASSEMBLER) - -#endif // LinkBuffer_h |