JSC should be able to show disassembly for all generated JIT code
https://bugs.webkit.org/show_bug.cgi?id=89536
Reviewed by Gavin Barraclough.
Now instead of doing linkBuffer.finalizeCode(), you do
FINALIZE_CODE(linkBuffer, (... explanation ...)). FINALIZE_CODE() then
prints your explanation and the disassembled code, if
Options::showDisassembly is set to true.
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* assembler/LinkBuffer.cpp: Added.
(JSC):
(JSC::LinkBuffer::finalizeCodeWithoutDisassembly):
(JSC::LinkBuffer::finalizeCodeWithDisassembly):
(JSC::LinkBuffer::linkCode):
(JSC::LinkBuffer::performFinalization):
(JSC::LinkBuffer::dumpLinkStatistics):
(JSC::LinkBuffer::dumpCode):
* assembler/LinkBuffer.h:
(LinkBuffer):
(JSC):
* assembler/MacroAssemblerCodeRef.h:
(JSC::MacroAssemblerCodeRef::tryToDisassemble):
(MacroAssemblerCodeRef):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGRepatch.cpp:
(JSC::DFG::generateProtoChainAccessStub):
(JSC::DFG::tryCacheGetByID):
(JSC::DFG::tryBuildGetByIDList):
(JSC::DFG::emitPutReplaceStub):
(JSC::DFG::emitPutTransitionStub):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrExitGenerationThunkGenerator):
* disassembler/Disassembler.h:
(JSC):
(JSC::tryToDisassemble):
* disassembler/UDis86Disassembler.cpp:
(JSC::tryToDisassemble):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITCode.h:
(JSC::JITCode::tryToDisassemble):
* jit/JITOpcodes.cpp:
(JSC::JIT::privateCompileCTIMachineTrampolines):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileCTIMachineTrampolines):
(JSC::JIT::privateCompileCTINativeCall):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::stringGetByValStubGenerator):
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::stringGetByValStubGenerator):
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
* jit/SpecializedThunkJIT.h:
(JSC::SpecializedThunkJIT::finalize):
* jit/ThunkGenerators.cpp:
(JSC::charCodeAtThunkGenerator):
(JSC::charAtThunkGenerator):
(JSC::fromCharCodeThunkGenerator):
(JSC::sqrtThunkGenerator):
(JSC::floorThunkGenerator):
(JSC::ceilThunkGenerator):
(JSC::roundThunkGenerator):
(JSC::expThunkGenerator):
(JSC::logThunkGenerator):
(JSC::absThunkGenerator):
(JSC::powThunkGenerator):
* llint/LLIntThunks.cpp:
(JSC::LLInt::generateThunkWithJumpTo):
(JSC::LLInt::functionForCallEntryThunkGenerator):
(JSC::LLInt::functionForConstructEntryThunkGenerator):
(JSC::LLInt::functionForCallArityCheckThunkGenerator):
(JSC::LLInt::functionForConstructArityCheckThunkGenerator):
(JSC::LLInt::evalEntryThunkGenerator):
(JSC::LLInt::programEntryThunkGenerator):
* runtime/Options.cpp:
(Options):
(JSC::Options::initializeOptions):
* runtime/Options.h:
(Options):
* yarr/YarrJIT.cpp:
(JSC::Yarr::YarrGenerator::compile):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@120786 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 47e8794..24e67b9 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -36,6 +36,8 @@
API/JSValueRef.cpp
API/JSWeakObjectMapRefPrivate.cpp
API/OpaqueJSString.cpp
+
+ assembler/LinkBuffer.cpp
bytecode/CallLinkInfo.cpp
bytecode/CallLinkStatus.cpp
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 8338c86..aafc84d 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,108 @@
+2012-06-19 Filip Pizlo <fpizlo@apple.com>
+
+ JSC should be able to show disassembly for all generated JIT code
+ https://bugs.webkit.org/show_bug.cgi?id=89536
+
+ Reviewed by Gavin Barraclough.
+
+ Now instead of doing linkBuffer.finalizeCode(), you do
+ FINALIZE_CODE(linkBuffer, (... explanation ...)). FINALIZE_CODE() then
+ prints your explanation and the disassembled code, if
+ Options::showDisassembly is set to true.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * assembler/LinkBuffer.cpp: Added.
+ (JSC):
+ (JSC::LinkBuffer::finalizeCodeWithoutDisassembly):
+ (JSC::LinkBuffer::finalizeCodeWithDisassembly):
+ (JSC::LinkBuffer::linkCode):
+ (JSC::LinkBuffer::performFinalization):
+ (JSC::LinkBuffer::dumpLinkStatistics):
+ (JSC::LinkBuffer::dumpCode):
+ * assembler/LinkBuffer.h:
+ (LinkBuffer):
+ (JSC):
+ * assembler/MacroAssemblerCodeRef.h:
+ (JSC::MacroAssemblerCodeRef::tryToDisassemble):
+ (MacroAssemblerCodeRef):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::compile):
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::generateProtoChainAccessStub):
+ (JSC::DFG::tryCacheGetByID):
+ (JSC::DFG::tryBuildGetByIDList):
+ (JSC::DFG::emitPutReplaceStub):
+ (JSC::DFG::emitPutTransitionStub):
+ * dfg/DFGThunks.cpp:
+ (JSC::DFG::osrExitGenerationThunkGenerator):
+ * disassembler/Disassembler.h:
+ (JSC):
+ (JSC::tryToDisassemble):
+ * disassembler/UDis86Disassembler.cpp:
+ (JSC::tryToDisassemble):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * jit/JITCode.h:
+ (JSC::JITCode::tryToDisassemble):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::privateCompileCTINativeCall):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::stringGetByValStubGenerator):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::stringGetByValStubGenerator):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::finalize):
+ * jit/ThunkGenerators.cpp:
+ (JSC::charCodeAtThunkGenerator):
+ (JSC::charAtThunkGenerator):
+ (JSC::fromCharCodeThunkGenerator):
+ (JSC::sqrtThunkGenerator):
+ (JSC::floorThunkGenerator):
+ (JSC::ceilThunkGenerator):
+ (JSC::roundThunkGenerator):
+ (JSC::expThunkGenerator):
+ (JSC::logThunkGenerator):
+ (JSC::absThunkGenerator):
+ (JSC::powThunkGenerator):
+ * llint/LLIntThunks.cpp:
+ (JSC::LLInt::generateThunkWithJumpTo):
+ (JSC::LLInt::functionForCallEntryThunkGenerator):
+ (JSC::LLInt::functionForConstructEntryThunkGenerator):
+ (JSC::LLInt::functionForCallArityCheckThunkGenerator):
+ (JSC::LLInt::functionForConstructArityCheckThunkGenerator):
+ (JSC::LLInt::evalEntryThunkGenerator):
+ (JSC::LLInt::programEntryThunkGenerator):
+ * runtime/Options.cpp:
+ (Options):
+ (JSC::Options::initializeOptions):
+ * runtime/Options.h:
+ (Options):
+ * yarr/YarrJIT.cpp:
+ (JSC::Yarr::YarrGenerator::compile):
+
2012-06-19 Mark Hahnenberg <mhahnenberg@apple.com>
[Qt][Mac] REGRESSION(r120742): It broke the build
diff --git a/Source/JavaScriptCore/GNUmakefile.list.am b/Source/JavaScriptCore/GNUmakefile.list.am
index 63a6c6f..77409fe 100644
--- a/Source/JavaScriptCore/GNUmakefile.list.am
+++ b/Source/JavaScriptCore/GNUmakefile.list.am
@@ -65,6 +65,7 @@
Source/JavaScriptCore/assembler/AssemblerBuffer.h \
Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h \
Source/JavaScriptCore/assembler/CodeLocation.h \
+ Source/JavaScriptCore/assembler/LinkBuffer.cpp \
Source/JavaScriptCore/assembler/LinkBuffer.h \
Source/JavaScriptCore/assembler/MacroAssembler.h \
Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp \
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index 2ffb2b5..78ca7dd 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -1738,6 +1738,10 @@
>
</File>
<File
+ RelativePath="..\..\assembler\LinkBuffer.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\assembler\LinkBuffer.h"
>
</File>
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index cd9733f..2ffc9e2 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -208,6 +208,7 @@
0FF4274A158EBE91004CB9FF /* udis86.c in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4273E158EBD94004CB9FF /* udis86.c */; };
0FF4274B158EBE91004CB9FF /* udis86.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF4273F158EBD94004CB9FF /* udis86.h */; };
0FF4274D158EBFE6004CB9FF /* udis86_itab_holder.c in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4274C158EBFE1004CB9FF /* udis86_itab_holder.c */; };
+ 0FF4275715914A20004CB9FF /* LinkBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4275615914A20004CB9FF /* LinkBuffer.cpp */; };
0FF922D414F46B410041A24E /* LLIntOffsetsExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */; };
0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */; };
0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -927,6 +928,7 @@
0FF4273E158EBD94004CB9FF /* udis86.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = udis86.c; path = disassembler/udis86/udis86.c; sourceTree = "<group>"; };
0FF4273F158EBD94004CB9FF /* udis86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = udis86.h; path = disassembler/udis86/udis86.h; sourceTree = "<group>"; };
0FF4274C158EBFE1004CB9FF /* udis86_itab_holder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = udis86_itab_holder.c; path = disassembler/udis86/udis86_itab_holder.c; sourceTree = "<group>"; };
+ 0FF4275615914A20004CB9FF /* LinkBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinkBuffer.cpp; sourceTree = "<group>"; };
0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCFAPhase.cpp; path = dfg/DFGCFAPhase.cpp; sourceTree = "<group>"; };
0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFAPhase.h; path = dfg/DFGCFAPhase.h; sourceTree = "<group>"; };
@@ -2295,6 +2297,7 @@
9688CB130ED12B4E001D649F /* AssemblerBuffer.h */,
86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */,
86E116B00FE75AC800B512BC /* CodeLocation.h */,
+ 0FF4275615914A20004CB9FF /* LinkBuffer.cpp */,
86D3B3C110159D7F002865E7 /* LinkBuffer.h */,
86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */,
86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */,
@@ -3340,6 +3343,7 @@
0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
0FF4274D158EBFE6004CB9FF /* udis86_itab_holder.c in Sources */,
C2E526BD1590EF000054E48D /* HeapTimer.cpp in Sources */,
+ 0FF4275715914A20004CB9FF /* LinkBuffer.cpp in Sources */,
C2D58C3415912FEE0021A844 /* GCActivityCallback.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/Source/JavaScriptCore/Target.pri b/Source/JavaScriptCore/Target.pri
index d16cf99..e3488c7 100644
--- a/Source/JavaScriptCore/Target.pri
+++ b/Source/JavaScriptCore/Target.pri
@@ -47,6 +47,7 @@
API/OpaqueJSString.cpp \
assembler/ARMAssembler.cpp \
assembler/ARMv7Assembler.cpp \
+ assembler/LinkBuffer.cpp \
assembler/MacroAssemblerARM.cpp \
assembler/MacroAssemblerSH4.cpp \
bytecode/CallLinkInfo.cpp \
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.cpp b/Source/JavaScriptCore/assembler/LinkBuffer.cpp
new file mode 100644
index 0000000..58030ba
--- /dev/null
+++ b/Source/JavaScriptCore/assembler/LinkBuffer.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LinkBuffer.h"
+
+#if ENABLE(ASSEMBLER)
+
+#include "Options.h"
+
+namespace JSC {
+
+LinkBuffer::CodeRef LinkBuffer::finalizeCodeWithoutDisassembly()
+{
+ performFinalization();
+
+ return CodeRef(m_executableMemory);
+}
+
+LinkBuffer::CodeRef LinkBuffer::finalizeCodeWithDisassembly(const char* format, ...)
+{
+ ASSERT(Options::showDisassembly);
+
+ CodeRef result = finalizeCodeWithoutDisassembly();
+
+ dataLog("Generated JIT code for ");
+ va_list argList;
+ va_start(argList, format);
+ WTF::dataLogV(format, argList);
+ va_end(argList);
+ dataLog(":\n");
+
+ dataLog(" Code at [%p, %p):\n", result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());
+ if (!tryToDisassemble(result.code(), m_size, " ", WTF::dataFile()))
+ dataLog(" <no disassembly available>");
+
+ return result;
+}
+
+void LinkBuffer::linkCode(void* ownerUID, JITCompilationEffort effort)
+{
+ ASSERT(!m_code);
+#if !ENABLE(BRANCH_COMPACTION)
+ m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData, ownerUID, effort);
+ if (!m_executableMemory)
+ return;
+ m_code = m_executableMemory->start();
+ m_size = m_assembler->m_assembler.codeSize();
+ ASSERT(m_code);
+#else
+ m_initialSize = m_assembler->m_assembler.codeSize();
+ m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort);
+ if (!m_executableMemory)
+ return;
+ m_code = (uint8_t*)m_executableMemory->start();
+ ASSERT(m_code);
+ ExecutableAllocator::makeWritable(m_code, m_initialSize);
+ uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode();
+ uint8_t* outData = reinterpret_cast<uint8_t*>(m_code);
+ int readPtr = 0;
+ int writePtr = 0;
+ Vector<LinkRecord>& jumpsToLink = m_assembler->jumpsToLink();
+ unsigned jumpCount = jumpsToLink.size();
+ for (unsigned i = 0; i < jumpCount; ++i) {
+ int offset = readPtr - writePtr;
+ ASSERT(!(offset & 1));
+
+ // Copy the instructions from the last jump to the current one.
+ size_t regionSize = jumpsToLink[i].from() - readPtr;
+ uint16_t* copySource = reinterpret_cast_ptr<uint16_t*>(inData + readPtr);
+ uint16_t* copyEnd = reinterpret_cast_ptr<uint16_t*>(inData + readPtr + regionSize);
+ uint16_t* copyDst = reinterpret_cast_ptr<uint16_t*>(outData + writePtr);
+ ASSERT(!(regionSize % 2));
+ ASSERT(!(readPtr % 2));
+ ASSERT(!(writePtr % 2));
+ while (copySource != copyEnd)
+ *copyDst++ = *copySource++;
+ m_assembler->recordLinkOffsets(readPtr, jumpsToLink[i].from(), offset);
+ readPtr += regionSize;
+ writePtr += regionSize;
+
+ // Calculate absolute address of the jump target, in the case of backwards
+ // branches we need to be precise, forward branches we are pessimistic
+ const uint8_t* target;
+ if (jumpsToLink[i].to() >= jumpsToLink[i].from())
+ target = outData + jumpsToLink[i].to() - offset; // Compensate for what we have collapsed so far
+ else
+ target = outData + jumpsToLink[i].to() - m_assembler->executableOffsetFor(jumpsToLink[i].to());
+
+ JumpLinkType jumpLinkType = m_assembler->computeJumpType(jumpsToLink[i], outData + writePtr, target);
+ // Compact branch if we can...
+ if (m_assembler->canCompact(jumpsToLink[i].type())) {
+ // Step back in the write stream
+ int32_t delta = m_assembler->jumpSizeDelta(jumpsToLink[i].type(), jumpLinkType);
+ if (delta) {
+ writePtr -= delta;
+ m_assembler->recordLinkOffsets(jumpsToLink[i].from() - delta, readPtr, readPtr - writePtr);
+ }
+ }
+ jumpsToLink[i].setFrom(writePtr);
+ }
+ // Copy everything after the last jump
+ memcpy(outData + writePtr, inData + readPtr, m_initialSize - readPtr);
+ m_assembler->recordLinkOffsets(readPtr, m_initialSize, readPtr - writePtr);
+
+ for (unsigned i = 0; i < jumpCount; ++i) {
+ uint8_t* location = outData + jumpsToLink[i].from();
+ uint8_t* target = outData + jumpsToLink[i].to() - m_assembler->executableOffsetFor(jumpsToLink[i].to());
+ m_assembler->link(jumpsToLink[i], location, target);
+ }
+
+ jumpsToLink.clear();
+ m_size = writePtr + m_initialSize - readPtr;
+ m_executableMemory->shrink(m_size);
+
+#if DUMP_LINK_STATISTICS
+ dumpLinkStatistics(m_code, m_initialSize, m_size);
+#endif
+#if DUMP_CODE
+ dumpCode(m_code, m_size);
+#endif
+#endif
+}
+
+void LinkBuffer::performFinalization()
+{
+#ifndef NDEBUG
+ ASSERT(!m_completed);
+ ASSERT(isValid());
+ m_completed = true;
+#endif
+
+#if ENABLE(BRANCH_COMPACTION)
+ ExecutableAllocator::makeExecutable(code(), m_initialSize);
+#else
+ ExecutableAllocator::makeExecutable(code(), m_size);
+#endif
+ MacroAssembler::cacheFlush(code(), m_size);
+}
+
+#if DUMP_LINK_STATISTICS
+void LinkBuffer::dumpLinkStatistics(void* code, size_t initializeSize, size_t finalSize)
+{
+ static unsigned linkCount = 0;
+ static unsigned totalInitialSize = 0;
+ static unsigned totalFinalSize = 0;
+ linkCount++;
+ totalInitialSize += initialSize;
+ totalFinalSize += finalSize;
+ dataLog("link %p: orig %u, compact %u (delta %u, %.2f%%)\n",
+ code, static_cast<unsigned>(initialSize), static_cast<unsigned>(finalSize),
+ static_cast<unsigned>(initialSize - finalSize),
+ 100.0 * (initialSize - finalSize) / initialSize);
+ dataLog("\ttotal %u: orig %u, compact %u (delta %u, %.2f%%)\n",
+ linkCount, totalInitialSize, totalFinalSize, totalInitialSize - totalFinalSize,
+ 100.0 * (totalInitialSize - totalFinalSize) / totalInitialSize);
+}
+#endif
+
+#if DUMP_CODE
+void LinkBuffer::dumpCode(void* code, size_t size)
+{
+#if CPU(ARM_THUMB2)
+ // Dump the generated code in an asm file format that can be assembled and then disassembled
+ // for debugging purposes. For example, save this output as jit.s:
+ // gcc -arch armv7 -c jit.s
+ // otool -tv jit.o
+ static unsigned codeCount = 0;
+ unsigned short* tcode = static_cast<unsigned short*>(code);
+ size_t tsize = size / sizeof(short);
+ char nameBuf[128];
+ snprintf(nameBuf, sizeof(nameBuf), "_jsc_jit%u", codeCount++);
+ dataLog("\t.syntax unified\n"
+ "\t.section\t__TEXT,__text,regular,pure_instructions\n"
+ "\t.globl\t%s\n"
+ "\t.align 2\n"
+ "\t.code 16\n"
+ "\t.thumb_func\t%s\n"
+ "# %p\n"
+ "%s:\n", nameBuf, nameBuf, code, nameBuf);
+
+ for (unsigned i = 0; i < tsize; i++)
+ dataLog("\t.short\t0x%x\n", tcode[i]);
+#elif CPU(ARM_TRADITIONAL)
+ // gcc -c jit.s
+ // objdump -D jit.o
+ static unsigned codeCount = 0;
+ unsigned int* tcode = static_cast<unsigned int*>(code);
+ size_t tsize = size / sizeof(unsigned int);
+ char nameBuf[128];
+ snprintf(nameBuf, sizeof(nameBuf), "_jsc_jit%u", codeCount++);
+ dataLog("\t.globl\t%s\n"
+ "\t.align 4\n"
+ "\t.code 32\n"
+ "\t.text\n"
+ "# %p\n"
+ "%s:\n", nameBuf, code, nameBuf);
+
+ for (unsigned i = 0; i < tsize; i++)
+ dataLog("\t.long\t0x%x\n", tcode[i]);
+#endif
+}
+#endif
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.h b/Source/JavaScriptCore/assembler/LinkBuffer.h
index eff320d..c6e0031 100644
--- a/Source/JavaScriptCore/assembler/LinkBuffer.h
+++ b/Source/JavaScriptCore/assembler/LinkBuffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -193,13 +193,13 @@
return applyOffset(label.m_label).m_offset;
}
- // Upon completion of all patching 'finalizeCode()' should be called once to complete generation of the code.
- CodeRef finalizeCode()
- {
- performFinalization();
-
- return CodeRef(m_executableMemory);
- }
+ // Upon completion of all patching 'FINALIZE_CODE()' should be called once to
+ // complete generation of the code. Alternatively, call
+ // finalizeCodeWithoutDisassembly() directly if you have your own way of
+ // displaying disassembly.
+
+ CodeRef finalizeCodeWithoutDisassembly();
+ CodeRef finalizeCodeWithDisassembly(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
CodePtr trampolineAt(Label label)
{
@@ -231,169 +231,16 @@
return m_code;
}
- void linkCode(void* ownerUID, JITCompilationEffort effort)
- {
- ASSERT(!m_code);
-#if !ENABLE(BRANCH_COMPACTION)
- m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData, ownerUID, effort);
- if (!m_executableMemory)
- return;
- m_code = m_executableMemory->start();
- m_size = m_assembler->m_assembler.codeSize();
- ASSERT(m_code);
-#else
- m_initialSize = m_assembler->m_assembler.codeSize();
- m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort);
- if (!m_executableMemory)
- return;
- m_code = (uint8_t*)m_executableMemory->start();
- ASSERT(m_code);
- ExecutableAllocator::makeWritable(m_code, m_initialSize);
- uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode();
- uint8_t* outData = reinterpret_cast<uint8_t*>(m_code);
- int readPtr = 0;
- int writePtr = 0;
- Vector<LinkRecord>& jumpsToLink = m_assembler->jumpsToLink();
- unsigned jumpCount = jumpsToLink.size();
- for (unsigned i = 0; i < jumpCount; ++i) {
- int offset = readPtr - writePtr;
- ASSERT(!(offset & 1));
-
- // Copy the instructions from the last jump to the current one.
- size_t regionSize = jumpsToLink[i].from() - readPtr;
- uint16_t* copySource = reinterpret_cast_ptr<uint16_t*>(inData + readPtr);
- uint16_t* copyEnd = reinterpret_cast_ptr<uint16_t*>(inData + readPtr + regionSize);
- uint16_t* copyDst = reinterpret_cast_ptr<uint16_t*>(outData + writePtr);
- ASSERT(!(regionSize % 2));
- ASSERT(!(readPtr % 2));
- ASSERT(!(writePtr % 2));
- while (copySource != copyEnd)
- *copyDst++ = *copySource++;
- m_assembler->recordLinkOffsets(readPtr, jumpsToLink[i].from(), offset);
- readPtr += regionSize;
- writePtr += regionSize;
-
- // Calculate absolute address of the jump target, in the case of backwards
- // branches we need to be precise, forward branches we are pessimistic
- const uint8_t* target;
- if (jumpsToLink[i].to() >= jumpsToLink[i].from())
- target = outData + jumpsToLink[i].to() - offset; // Compensate for what we have collapsed so far
- else
- target = outData + jumpsToLink[i].to() - m_assembler->executableOffsetFor(jumpsToLink[i].to());
-
- JumpLinkType jumpLinkType = m_assembler->computeJumpType(jumpsToLink[i], outData + writePtr, target);
- // Compact branch if we can...
- if (m_assembler->canCompact(jumpsToLink[i].type())) {
- // Step back in the write stream
- int32_t delta = m_assembler->jumpSizeDelta(jumpsToLink[i].type(), jumpLinkType);
- if (delta) {
- writePtr -= delta;
- m_assembler->recordLinkOffsets(jumpsToLink[i].from() - delta, readPtr, readPtr - writePtr);
- }
- }
- jumpsToLink[i].setFrom(writePtr);
- }
- // Copy everything after the last jump
- memcpy(outData + writePtr, inData + readPtr, m_initialSize - readPtr);
- m_assembler->recordLinkOffsets(readPtr, m_initialSize, readPtr - writePtr);
-
- for (unsigned i = 0; i < jumpCount; ++i) {
- uint8_t* location = outData + jumpsToLink[i].from();
- uint8_t* target = outData + jumpsToLink[i].to() - m_assembler->executableOffsetFor(jumpsToLink[i].to());
- m_assembler->link(jumpsToLink[i], location, target);
- }
+ void linkCode(void* ownerUID, JITCompilationEffort);
- jumpsToLink.clear();
- m_size = writePtr + m_initialSize - readPtr;
- m_executableMemory->shrink(m_size);
+ void performFinalization();
#if DUMP_LINK_STATISTICS
- dumpLinkStatistics(m_code, m_initialSize, m_size);
-#endif
-#if DUMP_CODE
- dumpCode(m_code, m_size);
-#endif
-#endif
- }
-
- void performFinalization()
- {
-#ifndef NDEBUG
- ASSERT(!m_completed);
- ASSERT(isValid());
- m_completed = true;
-#endif
-
-#if ENABLE(BRANCH_COMPACTION)
- ExecutableAllocator::makeExecutable(code(), m_initialSize);
-#else
- ExecutableAllocator::makeExecutable(code(), m_size);
-#endif
- MacroAssembler::cacheFlush(code(), m_size);
- }
-
-#if DUMP_LINK_STATISTICS
- static void dumpLinkStatistics(void* code, size_t initialSize, size_t finalSize)
- {
- static unsigned linkCount = 0;
- static unsigned totalInitialSize = 0;
- static unsigned totalFinalSize = 0;
- linkCount++;
- totalInitialSize += initialSize;
- totalFinalSize += finalSize;
- dataLog("link %p: orig %u, compact %u (delta %u, %.2f%%)\n",
- code, static_cast<unsigned>(initialSize), static_cast<unsigned>(finalSize),
- static_cast<unsigned>(initialSize - finalSize),
- 100.0 * (initialSize - finalSize) / initialSize);
- dataLog("\ttotal %u: orig %u, compact %u (delta %u, %.2f%%)\n",
- linkCount, totalInitialSize, totalFinalSize, totalInitialSize - totalFinalSize,
- 100.0 * (totalInitialSize - totalFinalSize) / totalInitialSize);
- }
+ static void dumpLinkStatistics(void* code, size_t initialSize, size_t finalSize);
#endif
#if DUMP_CODE
- static void dumpCode(void* code, size_t size)
- {
-#if CPU(ARM_THUMB2)
- // Dump the generated code in an asm file format that can be assembled and then disassembled
- // for debugging purposes. For example, save this output as jit.s:
- // gcc -arch armv7 -c jit.s
- // otool -tv jit.o
- static unsigned codeCount = 0;
- unsigned short* tcode = static_cast<unsigned short*>(code);
- size_t tsize = size / sizeof(short);
- char nameBuf[128];
- snprintf(nameBuf, sizeof(nameBuf), "_jsc_jit%u", codeCount++);
- dataLog("\t.syntax unified\n"
- "\t.section\t__TEXT,__text,regular,pure_instructions\n"
- "\t.globl\t%s\n"
- "\t.align 2\n"
- "\t.code 16\n"
- "\t.thumb_func\t%s\n"
- "# %p\n"
- "%s:\n", nameBuf, nameBuf, code, nameBuf);
-
- for (unsigned i = 0; i < tsize; i++)
- dataLog("\t.short\t0x%x\n", tcode[i]);
-#elif CPU(ARM_TRADITIONAL)
- // gcc -c jit.s
- // objdump -D jit.o
- static unsigned codeCount = 0;
- unsigned int* tcode = static_cast<unsigned int*>(code);
- size_t tsize = size / sizeof(unsigned int);
- char nameBuf[128];
- snprintf(nameBuf, sizeof(nameBuf), "_jsc_jit%u", codeCount++);
- dataLog("\t.globl\t%s\n"
- "\t.align 4\n"
- "\t.code 32\n"
- "\t.text\n"
- "# %p\n"
- "%s:\n", nameBuf, code, nameBuf);
-
- for (unsigned i = 0; i < tsize; i++)
- dataLog("\t.long\t0x%x\n", tcode[i]);
-#endif
- }
+ static void dumpCode(void* code, size_t);
#endif
RefPtr<ExecutableMemoryHandle> m_executableMemory;
@@ -410,6 +257,27 @@
#endif
};
+// Use this to finalize code, like so:
+//
+// CodeRef code = FINALIZE_CODE(linkBuffer, ("my super thingy number %d", number));
+//
+// Which, in disassembly mode, will print:
+//
+// Generated JIT code for my super thingy number 42:
+// Code at [0x123456, 0x234567]:
+// 0x123456: mov $0, 0
+// 0x12345a: ret
+//
+// ... and so on.
+//
+// Note that the dataLogArgumentsForHeading are only evaluated when showDisassembly
+// is true, so you can hide expensive disassembly-only computations inside there.
+
+#define FINALIZE_CODE(linkBufferReference, dataLogArgumentsForHeading) \
+ (UNLIKELY(Options::showDisassembly) \
+ ? ((linkBufferReference).finalizeCodeWithDisassembly dataLogArgumentsForHeading) \
+ : (linkBufferReference).finalizeCodeWithoutDisassembly())
+
} // namespace JSC
#endif // ENABLE(ASSEMBLER)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
index ac62c42..a1b3a83 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,7 +26,9 @@
#ifndef MacroAssemblerCodeRef_h
#define MacroAssemblerCodeRef_h
+#include "Disassembler.h"
#include "ExecutableAllocator.h"
+#include <wtf/DataLog.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/UnusedParam.h>
@@ -367,6 +369,11 @@
return m_executableMemory->sizeInBytes();
}
+ bool tryToDisassemble(const char* prefix) const
+ {
+ return JSC::tryToDisassemble(m_codePtr, size(), prefix, WTF::dataFile());
+ }
+
bool operator!() const { return !m_codePtr; }
private:
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
index c0eeca8..561f516 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
@@ -220,10 +220,9 @@
link(linkBuffer);
speculative.linkOSREntries(linkBuffer);
- entry = JITCode(linkBuffer.finalizeCode(), JITCode::DFGJIT);
-#if DFG_ENABLE(DEBUG_VERBOSE)
- entry.tryToDisassemble();
-#endif
+ entry = JITCode(
+ FINALIZE_CODE(linkBuffer, ("DFG program/eval CodeBlock %p", m_codeBlock)),
+ JITCode::DFGJIT);
return true;
}
@@ -305,10 +304,9 @@
linkBuffer.link(callArityCheck, m_codeBlock->m_isConstructor ? cti_op_construct_arityCheck : cti_op_call_arityCheck);
entryWithArityCheck = linkBuffer.locationOf(arityCheck);
- entry = JITCode(linkBuffer.finalizeCode(), JITCode::DFGJIT);
-#if DFG_ENABLE(DEBUG_VERBOSE)
- entry.tryToDisassemble();
-#endif
+ entry = JITCode(
+ FINALIZE_CODE(linkBuffer, ("DFG function CodeBlock %p", m_codeBlock)),
+ JITCode::DFGJIT);
return true;
}
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
index 888a4a2..d46d596 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
@@ -79,11 +79,11 @@
exitCompiler.compileExit(exit, recovery);
LinkBuffer patchBuffer(*globalData, &jit, codeBlock);
- exit.m_code = patchBuffer.finalizeCode();
-
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLog("OSR exit code at [%p, %p).\n", patchBuffer.debugAddress(), static_cast<char*>(patchBuffer.debugAddress()) + patchBuffer.debugSize());
-#endif
+ exit.m_code = FINALIZE_CODE(
+ patchBuffer,
+ ("DFG OSR exit #%u (bc#%u, @%u, %s) from CodeBlock %p",
+ exitIndex, exit.m_codeOrigin.bytecodeIndex, exit.m_nodeIndex,
+ exitKindToString(exit.m_kind), codeBlock));
}
{
diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
index 2c07ed5..9c3391b 100644
--- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp
+++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
@@ -155,7 +155,10 @@
linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, successLabel, slowCaseLabel);
- stubRoutine = patchBuffer.finalizeCode();
+ stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("DFG prototype chain access stub for CodeBlock %p, return point %p",
+ exec->codeBlock(), successLabel.executableAddress()));
}
static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
@@ -206,7 +209,11 @@
linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCases);
- stubInfo.stubRoutine = patchBuffer.finalizeCode();
+ stubInfo.stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("DFG GetById array length stub for CodeBlock %p, return point %p",
+ exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
+ stubInfo.patch.dfg.deltaCallToDone).executableAddress()));
RepatchBuffer repatchBuffer(codeBlock);
repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck), CodeLocationLabel(stubInfo.stubRoutine.code()));
@@ -405,7 +412,11 @@
patchBuffer.link(handlerCall, lookupExceptionHandlerInStub);
}
- MacroAssemblerCodeRef stubRoutine = patchBuffer.finalizeCode();
+ MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("DFG GetById polymorphic list access for CodeBlock %p, return point %p",
+ exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
+ stubInfo.patch.dfg.deltaCallToDone).executableAddress()));
polymorphicStructureList->list[listIndex].set(*globalData, codeBlock->ownerExecutable(), stubRoutine, structure, isDirect);
@@ -611,7 +622,11 @@
patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone));
patchBuffer.link(failure, failureLabel);
- stubRoutine = patchBuffer.finalizeCode();
+ stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("DFG PutById replace stub for CodeBlock %p, return point %p",
+ exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
+ stubInfo.patch.dfg.deltaCallToDone).executableAddress()));
}
static void emitPutTransitionStub(
@@ -707,7 +722,11 @@
else
patchBuffer.link(failureCases, failureLabel);
- stubRoutine = patchBuffer.finalizeCode();
+ stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("DFG PutById transition stub for CodeBlock %p, return point %p",
+ exec->codeBlock(), stubInfo.callReturnLocation.labelAtOffset(
+ stubInfo.patch.dfg.deltaCallToDone).executableAddress()));
}
static bool tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier& ident, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
diff --git a/Source/JavaScriptCore/dfg/DFGThunks.cpp b/Source/JavaScriptCore/dfg/DFGThunks.cpp
index 1ed46c1..08ca6ea 100644
--- a/Source/JavaScriptCore/dfg/DFGThunks.cpp
+++ b/Source/JavaScriptCore/dfg/DFGThunks.cpp
@@ -79,7 +79,7 @@
patchBuffer.link(functionCall, compileOSRExit);
- return patchBuffer.finalizeCode();
+ return FINALIZE_CODE(patchBuffer, ("DFG OSR exit generation thunk"));
}
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/disassembler/Disassembler.h b/Source/JavaScriptCore/disassembler/Disassembler.h
index e49defd..7d7400a 100644
--- a/Source/JavaScriptCore/disassembler/Disassembler.h
+++ b/Source/JavaScriptCore/disassembler/Disassembler.h
@@ -26,16 +26,18 @@
#ifndef Disassembler_h
#define Disassembler_h
-#include "MacroAssemblerCodeRef.h"
+#include <stdio.h>
#include <wtf/Platform.h>
#include <wtf/StdLibExtras.h>
namespace JSC {
+class MacroAssemblerCodePtr;
+
#if ENABLE(DISASSEMBLER)
-bool tryToDisassemble(MacroAssemblerCodePtr, size_t size, FILE* out);
+bool tryToDisassemble(const MacroAssemblerCodePtr&, size_t, const char* prefix, FILE* out);
#else
-inline bool tryToDisassemble(MacroAssemblerCodePtr, size_t, FILE*)
+inline bool tryToDisassemble(const MacroAssemblerCodePtr&, size_t, const char*, FILE*)
{
return false;
}
diff --git a/Source/JavaScriptCore/disassembler/UDis86Disassembler.cpp b/Source/JavaScriptCore/disassembler/UDis86Disassembler.cpp
index 26ec23b..b6baed4 100644
--- a/Source/JavaScriptCore/disassembler/UDis86Disassembler.cpp
+++ b/Source/JavaScriptCore/disassembler/UDis86Disassembler.cpp
@@ -28,11 +28,12 @@
#if USE(UDIS86)
+#include "MacroAssemblerCodeRef.h"
#include "udis86.h"
namespace JSC {
-bool tryToDisassemble(MacroAssemblerCodePtr codePtr, size_t size, FILE* out)
+bool tryToDisassemble(const MacroAssemblerCodePtr& codePtr, size_t size, const char* prefix, FILE* out)
{
ud_t disassembler;
ud_init(&disassembler);
@@ -45,10 +46,12 @@
ud_set_pc(&disassembler, bitwise_cast<uintptr_t>(codePtr.executableAddress()));
ud_set_syntax(&disassembler, UD_SYN_ATT);
+ uint64_t currentPC = disassembler.pc;
while (ud_disassemble(&disassembler)) {
char pcString[20];
- snprintf(pcString, sizeof(pcString), "0x%lx", static_cast<unsigned long>(disassembler.pc));
- fprintf(out, "%16s: %s\n", pcString, ud_insn_asm(&disassembler));
+ snprintf(pcString, sizeof(pcString), "0x%lx", static_cast<unsigned long>(currentPC));
+ fprintf(out, "%s%16s: %s\n", prefix, pcString, ud_insn_asm(&disassembler));
+ currentPC = disassembler.pc;
}
return true;
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index d3ba991..2aca351 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -761,7 +761,8 @@
if (m_codeBlock->codeType() == FunctionCode && functionEntryArityCheck)
*functionEntryArityCheck = patchBuffer.locationOf(arityCheck);
- CodeRef result = patchBuffer.finalizeCode();
+ CodeRef result = FINALIZE_CODE(
+ patchBuffer, ("Baseline JIT code for CodeBlock %p", m_codeBlock));
m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT.add(
static_cast<double>(result.size()) /
diff --git a/Source/JavaScriptCore/jit/JITCode.h b/Source/JavaScriptCore/jit/JITCode.h
index 67df80a..478fcc7 100644
--- a/Source/JavaScriptCore/jit/JITCode.h
+++ b/Source/JavaScriptCore/jit/JITCode.h
@@ -145,9 +145,9 @@
return m_ref.size();
}
- bool tryToDisassemble() const
+ bool tryToDisassemble(const char* prefix) const
{
- return JSC::tryToDisassemble(m_ref.code(), size(), WTF::dataFile());
+ return m_ref.tryToDisassemble(prefix);
}
ExecutableMemoryHandle* getExecutableMemory()
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index 2288a06..ad7a56e 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -211,7 +211,7 @@
patchBuffer.link(callCallNotJSFunction, FunctionPtr(cti_op_call_NotJSFunction));
patchBuffer.link(callConstructNotJSFunction, FunctionPtr(cti_op_construct_NotJSConstruct));
- CodeRef finalCode = patchBuffer.finalizeCode();
+ CodeRef finalCode = FINALIZE_CODE(patchBuffer, ("JIT CTI machine trampolines"));
RefPtr<ExecutableMemoryHandle> executableMemory = finalCode.executableMemory();
trampolines->ctiVirtualCallLink = patchBuffer.trampolineAt(virtualCallLinkBegin);
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 2a8abf4..57ef7ef 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -207,7 +207,7 @@
patchBuffer.link(callCallNotJSFunction, FunctionPtr(cti_op_call_NotJSFunction));
patchBuffer.link(callConstructNotJSFunction, FunctionPtr(cti_op_construct_NotJSConstruct));
- CodeRef finalCode = patchBuffer.finalizeCode();
+ CodeRef finalCode = FINALIZE_CODE(patchBuffer, ("JIT CTI machine trampolines"));
RefPtr<ExecutableMemoryHandle> executableMemory = finalCode.executableMemory();
trampolines->ctiVirtualCallLink = patchBuffer.trampolineAt(virtualCallLinkBegin);
@@ -497,7 +497,7 @@
LinkBuffer patchBuffer(*m_globalData, this, GLOBAL_THUNK_ID);
patchBuffer.link(nativeCall, FunctionPtr(func));
- return patchBuffer.finalizeCode();
+ return FINALIZE_CODE(patchBuffer, ("JIT CTI native call"));
}
void JIT::emit_op_mov(Instruction* currentInstruction)
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index 4fb40aa..7478f91 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -88,7 +88,7 @@
jit.ret();
LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
- return patchBuffer.finalizeCode();
+ return FINALIZE_CODE(patchBuffer, ("String get_by_val stub"));
}
void JIT::emit_op_get_by_val(Instruction* currentInstruction)
@@ -564,7 +564,10 @@
patchBuffer.link(m_calls[0].from, FunctionPtr(cti_op_put_by_id_transition_realloc));
}
- stubInfo->stubRoutine = patchBuffer.finalizeCode();
+ stubInfo->stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline put_by_id transition for CodeBlock %p, return point %p",
+ m_codeBlock, returnAddress.value()));
RepatchBuffer repatchBuffer(m_codeBlock);
repatchBuffer.relinkCallerToTrampoline(returnAddress, CodeLocationLabel(stubInfo->stubRoutine.code()));
}
@@ -625,7 +628,11 @@
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
// Track the stub we have created so that it will be deleted later.
- stubInfo->stubRoutine = patchBuffer.finalizeCode();
+ stubInfo->stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Basline JIT get_by_id array length stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
@@ -688,7 +695,11 @@
}
}
// Track the stub we have created so that it will be deleted later.
- stubInfo->stubRoutine = patchBuffer.finalizeCode();
+ stubInfo->stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline JIT get_by_id proto stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
@@ -745,7 +756,11 @@
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
- MacroAssemblerCodeRef stubCode = patchBuffer.finalizeCode();
+ MacroAssemblerCodeRef stubCode = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline JIT get_by_id list stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, isDirect);
@@ -811,7 +826,11 @@
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
- MacroAssemblerCodeRef stubCode = patchBuffer.finalizeCode();
+ MacroAssemblerCodeRef stubCode = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline JIT get_by_id proto list stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
prototypeStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, prototypeStructure, isDirect);
// Finally patch the jump to slow case back in the hot path to jump here instead.
@@ -880,7 +899,11 @@
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
- CodeRef stubRoutine = patchBuffer.finalizeCode();
+ CodeRef stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline JIT get_by_id chain list stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
// Track the stub we have created so that it will be deleted later.
prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect);
@@ -947,7 +970,11 @@
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
// Track the stub we have created so that it will be deleted later.
- CodeRef stubRoutine = patchBuffer.finalizeCode();
+ CodeRef stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline JIT get_by_id chain stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
stubInfo->stubRoutine = stubRoutine;
// Finally patch the jump to slow case back in the hot path to jump here instead.
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 5bec19e..a44c576 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -194,7 +194,7 @@
jit.ret();
LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
- return patchBuffer.finalizeCode();
+ return FINALIZE_CODE(patchBuffer, ("String get_by_val stub"));
}
void JIT::emit_op_get_by_val(Instruction* currentInstruction)
@@ -545,7 +545,10 @@
patchBuffer.link(m_calls[0].from, FunctionPtr(cti_op_put_by_id_transition_realloc));
}
- stubInfo->stubRoutine = patchBuffer.finalizeCode();
+ stubInfo->stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline put_by_id transition stub for CodeBlock %p, return point %p",
+ m_codeBlock, returnAddress.value()));
RepatchBuffer repatchBuffer(m_codeBlock);
repatchBuffer.relinkCallerToTrampoline(returnAddress, CodeLocationLabel(stubInfo->stubRoutine.code()));
}
@@ -611,7 +614,11 @@
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
// Track the stub we have created so that it will be deleted later.
- stubInfo->stubRoutine = patchBuffer.finalizeCode();
+ stubInfo->stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline get_by_id array length stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
@@ -677,7 +684,11 @@
}
// Track the stub we have created so that it will be deleted later.
- stubInfo->stubRoutine = patchBuffer.finalizeCode();
+ stubInfo->stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline get_by_id proto stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
@@ -735,7 +746,11 @@
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
- CodeRef stubRoutine = patchBuffer.finalizeCode();
+ MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline get_by_id self list stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubRoutine, structure, isDirect);
@@ -800,7 +815,11 @@
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
- CodeRef stubRoutine = patchBuffer.finalizeCode();
+ MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline get_by_id proto list stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, prototypeStructure, isDirect);
@@ -870,7 +889,11 @@
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
- CodeRef stubRoutine = patchBuffer.finalizeCode();
+ MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline get_by_id chain list stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
// Track the stub we have created so that it will be deleted later.
prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect);
@@ -936,7 +959,11 @@
patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(stubInfo->patch.baseline.u.get.putResult));
// Track the stub we have created so that it will be deleted later.
- CodeRef stubRoutine = patchBuffer.finalizeCode();
+ MacroAssemblerCodeRef stubRoutine = FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline get_by_id chain stub for CodeBlock %p, return point %p",
+ m_codeBlock, stubInfo->hotPathBegin.labelAtOffset(
+ stubInfo->patch.baseline.u.get.putResult).executableAddress()));
stubInfo->stubRoutine = stubRoutine;
// Finally patch the jump to slow case back in the hot path to jump here instead.
diff --git a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
index 74e94ea..c98e57d1 100644
--- a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
+++ b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
@@ -132,13 +132,13 @@
ret();
}
- MacroAssemblerCodeRef finalize(JSGlobalData& globalData, MacroAssemblerCodePtr fallback)
+ MacroAssemblerCodeRef finalize(JSGlobalData& globalData, MacroAssemblerCodePtr fallback, const char* thunkKind)
{
LinkBuffer patchBuffer(globalData, this, GLOBAL_THUNK_ID);
patchBuffer.link(m_failures, CodeLocationLabel(fallback));
for (unsigned i = 0; i < m_calls.size(); i++)
patchBuffer.link(m_calls[i].first, m_calls[i].second);
- return patchBuffer.finalizeCode();
+ return FINALIZE_CODE(patchBuffer, ("Specialized thunk for %s", thunkKind));
}
// Assumes that the target function uses fpRegister0 as the first argument
diff --git a/Source/JavaScriptCore/jit/ThunkGenerators.cpp b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
index de8c938..c440b51 100644
--- a/Source/JavaScriptCore/jit/ThunkGenerators.cpp
+++ b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
@@ -78,7 +78,7 @@
SpecializedThunkJIT jit(1, globalData);
stringCharLoad(jit);
jit.returnInt32(SpecializedThunkJIT::regT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "charCodeAt");
}
MacroAssemblerCodeRef charAtThunkGenerator(JSGlobalData* globalData)
@@ -87,7 +87,7 @@
stringCharLoad(jit);
charToString(jit, globalData, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
jit.returnJSCell(SpecializedThunkJIT::regT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "charAt");
}
MacroAssemblerCodeRef fromCharCodeThunkGenerator(JSGlobalData* globalData)
@@ -97,7 +97,7 @@
jit.loadInt32Argument(0, SpecializedThunkJIT::regT0);
charToString(jit, globalData, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
jit.returnJSCell(SpecializedThunkJIT::regT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "fromCharCode");
}
MacroAssemblerCodeRef sqrtThunkGenerator(JSGlobalData* globalData)
@@ -109,7 +109,7 @@
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
jit.sqrtDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "sqrt");
}
@@ -209,7 +209,7 @@
jit.returnInt32(SpecializedThunkJIT::regT0);
doubleResult.link(&jit);
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "floor");
}
MacroAssemblerCodeRef ceilThunkGenerator(JSGlobalData* globalData)
@@ -228,7 +228,7 @@
jit.returnInt32(SpecializedThunkJIT::regT0);
doubleResult.link(&jit);
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "ceil");
}
MacroAssemblerCodeRef roundThunkGenerator(JSGlobalData* globalData)
@@ -262,7 +262,7 @@
jit.returnInt32(SpecializedThunkJIT::regT0);
doubleResult.link(&jit);
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "round");
}
MacroAssemblerCodeRef expThunkGenerator(JSGlobalData* globalData)
@@ -275,7 +275,7 @@
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
jit.callDoubleToDouble(UnaryDoubleOpWrapper(exp));
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "exp");
}
MacroAssemblerCodeRef logThunkGenerator(JSGlobalData* globalData)
@@ -288,7 +288,7 @@
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
jit.callDoubleToDouble(UnaryDoubleOpWrapper(log));
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "log");
}
MacroAssemblerCodeRef absThunkGenerator(JSGlobalData* globalData)
@@ -308,7 +308,7 @@
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
jit.absDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1);
jit.returnDouble(SpecializedThunkJIT::fpRegT1);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "abs");
}
MacroAssemblerCodeRef powThunkGenerator(JSGlobalData* globalData)
@@ -360,7 +360,7 @@
} else
jit.appendFailure(nonIntExponent);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall());
+ return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "pow");
}
}
diff --git a/Source/JavaScriptCore/llint/LLIntThunks.cpp b/Source/JavaScriptCore/llint/LLIntThunks.cpp
index b4d0264..6a6a579 100644
--- a/Source/JavaScriptCore/llint/LLIntThunks.cpp
+++ b/Source/JavaScriptCore/llint/LLIntThunks.cpp
@@ -36,7 +36,7 @@
namespace JSC { namespace LLInt {
-static MacroAssemblerCodeRef generateThunkWithJumpTo(JSGlobalData* globalData, void (*target)())
+static MacroAssemblerCodeRef generateThunkWithJumpTo(JSGlobalData* globalData, void (*target)(), const char *thunkKind)
{
JSInterfaceJIT jit;
@@ -45,37 +45,37 @@
jit.jump(JSInterfaceJIT::regT0);
LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
- return patchBuffer.finalizeCode();
+ return FINALIZE_CODE(patchBuffer, ("LLInt %s prologue thunk", thunkKind));
}
MacroAssemblerCodeRef functionForCallEntryThunkGenerator(JSGlobalData* globalData)
{
- return generateThunkWithJumpTo(globalData, llint_function_for_call_prologue);
+ return generateThunkWithJumpTo(globalData, llint_function_for_call_prologue, "function for call");
}
MacroAssemblerCodeRef functionForConstructEntryThunkGenerator(JSGlobalData* globalData)
{
- return generateThunkWithJumpTo(globalData, llint_function_for_construct_prologue);
+ return generateThunkWithJumpTo(globalData, llint_function_for_construct_prologue, "function for construct");
}
MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(JSGlobalData* globalData)
{
- return generateThunkWithJumpTo(globalData, llint_function_for_call_arity_check);
+ return generateThunkWithJumpTo(globalData, llint_function_for_call_arity_check, "function for call with arity check");
}
MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(JSGlobalData* globalData)
{
- return generateThunkWithJumpTo(globalData, llint_function_for_construct_arity_check);
+ return generateThunkWithJumpTo(globalData, llint_function_for_construct_arity_check, "function for construct with arity check");
}
MacroAssemblerCodeRef evalEntryThunkGenerator(JSGlobalData* globalData)
{
- return generateThunkWithJumpTo(globalData, llint_eval_prologue);
+ return generateThunkWithJumpTo(globalData, llint_eval_prologue, "eval");
}
MacroAssemblerCodeRef programEntryThunkGenerator(JSGlobalData* globalData)
{
- return generateThunkWithJumpTo(globalData, llint_program_prologue);
+ return generateThunkWithJumpTo(globalData, llint_program_prologue, "program");
}
} } // namespace JSC::LLInt
diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp
index 9e05939..ec228f8 100644
--- a/Source/JavaScriptCore/runtime/Options.cpp
+++ b/Source/JavaScriptCore/runtime/Options.cpp
@@ -47,6 +47,8 @@
bool useJIT;
+bool showDisassembly;
+
unsigned maximumOptimizationCandidateInstructionCount;
unsigned maximumFunctionForCallInlineCandidateInstructionCount;
@@ -162,6 +164,8 @@
{
SET(useJIT, true);
+ SET(showDisassembly, false);
+
SET(maximumOptimizationCandidateInstructionCount, 10000);
SET(maximumFunctionForCallInlineCandidateInstructionCount, 180);
diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h
index ac49109..e5cc995 100644
--- a/Source/JavaScriptCore/runtime/Options.h
+++ b/Source/JavaScriptCore/runtime/Options.h
@@ -32,6 +32,8 @@
extern bool useJIT;
+extern bool showDisassembly;
+
extern unsigned maximumOptimizationCandidateInstructionCount;
extern unsigned maximumFunctionForCallInlineCandidateInstructionCount;
diff --git a/Source/JavaScriptCore/yarr/YarrJIT.cpp b/Source/JavaScriptCore/yarr/YarrJIT.cpp
index 60519eb..eb9861f 100644
--- a/Source/JavaScriptCore/yarr/YarrJIT.cpp
+++ b/Source/JavaScriptCore/yarr/YarrJIT.cpp
@@ -2611,14 +2611,14 @@
if (compileMode == MatchOnly) {
if (m_charSize == Char8)
- jitObject.set8BitCodeMatchOnly(linkBuffer.finalizeCode());
+ jitObject.set8BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, ("Match-only 8-bit regular expression")));
else
- jitObject.set16BitCodeMatchOnly(linkBuffer.finalizeCode());
+ jitObject.set16BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, ("Match-only 16-bit regular expression")));
} else {
if (m_charSize == Char8)
- jitObject.set8BitCode(linkBuffer.finalizeCode());
+ jitObject.set8BitCode(FINALIZE_CODE(linkBuffer, ("8-bit regular expression")));
else
- jitObject.set16BitCode(linkBuffer.finalizeCode());
+ jitObject.set16BitCode(FINALIZE_CODE(linkBuffer, ("16-bit regular expression")));
}
jitObject.setFallBack(m_shouldFallBack);
}