From 096226088e568981d4111466840f70d55af99b6b Mon Sep 17 00:00:00 2001
From: Zoltan Herczeg <zherczeg@inf.u-szeged.hu>
Date: Tue, 28 Jul 2009 09:46:46 +0200
Subject: [PATCH] arm profile lib

Signed-off-by: Zoltan Herczeg <zherczeg@inf.u-szeged.hu>
---
 JavaScriptCore/JavaScriptCore.pri            |    2 ++
 JavaScriptCore/assembler/ARMAssembler.h      |   15 +++++++++++++++
 JavaScriptCore/assembler/MacroAssemblerARM.h |   16 ++++++++++++++++
 JavaScriptCore/jit/JIT.cpp                   |   20 ++++++++++++++++++++
 JavaScriptCore/jit/JITOpcodes.cpp            |    7 +++++++
 JavaScriptCore/jsc.cpp                       |    7 +++++++
 6 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/JavaScriptCore/JavaScriptCore.pri b/JavaScriptCore/JavaScriptCore.pri
index b87e420..ff7828b 100644
--- a/JavaScriptCore/JavaScriptCore.pri
+++ b/JavaScriptCore/JavaScriptCore.pri
@@ -65,6 +65,7 @@ contains(DEFINES, ENABLE_JIT=1) {
     win32-msvc* {
         !contains(DEFINES, WTF_USE_JIT_STUB_ARGUMENT_REGISTER=.): DEFINES += WTF_USE_JIT_STUB_ARGUMENT_REGISTER=1
     }
+    !contains(DEFINES, ENABLE_PROFILE_ARM=.): DEFINES += ENABLE_PROFILE_ARM=1
 }
 
 include(pcre/pcre.pri)
@@ -120,6 +121,7 @@ SOURCES += \
     bytecode/StructureStubInfo.cpp \
     bytecode/JumpTable.cpp \
     assembler/ARMAssembler.cpp \
+    assembler/ARMProfiler.cpp \
     jit/JIT.cpp \
     jit/JITCall.cpp \
     jit/JITArithmetic.cpp \
diff --git a/JavaScriptCore/assembler/ARMAssembler.h b/JavaScriptCore/assembler/ARMAssembler.h
index ed35c52..142d7d5 100644
--- a/JavaScriptCore/assembler/ARMAssembler.h
+++ b/JavaScriptCore/assembler/ARMAssembler.h
@@ -705,6 +705,21 @@ namespace ARM {
             return OP2_IMMh | (imm & 0x0f) | ((imm & 0xf0) << 4) ;
         }
 
+#ifdef ENABLE_PROFILE_ARM
+        // Profiling
+        void emitSampling(void* function, uint32_t index)
+        {
+            ensureSpace(7 * 4, 0);
+            m_buffer.putInt(0xe92d500f);
+            m_buffer.putInt(0xe59f0004);
+            m_buffer.putInt(0xe28fe008);
+            m_buffer.putInt(0xe59ff000);
+            m_buffer.putInt(index);
+            m_buffer.putInt(reinterpret_cast<intptr_t>(function));
+            m_buffer.putInt(0xe8bd500f);
+        }
+#endif // ENABLE_PROFILE_ARM
+
         static ARMWord getOp2(ARMWord imm);
         ARMWord getImm(ARMWord imm, int tmpReg, bool invert = false);
         void moveImm(ARMWord imm, int dest, bool limitToOneInstruction = false);
diff --git a/JavaScriptCore/assembler/MacroAssemblerARM.h b/JavaScriptCore/assembler/MacroAssemblerARM.h
index 85de420..dff6c0c 100644
--- a/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -34,6 +34,9 @@
 
 #include "ARMAssembler.h"
 #include "AbstractMacroAssembler.h"
+#ifdef ENABLE_PROFILE_ARM
+#include "ARMProfiler.h"
+#endif
 
 namespace JSC {
 
@@ -761,6 +764,19 @@ protected:
         }
     }
 
+#ifdef ENABLE_PROFILE_ARM
+    // Profiling
+    void emitStartSampling(uint32_t index)
+    {
+        m_assembler.emitSampling(reinterpret_cast<void*>(&ARMProfiler::startSampling), index);
+    }
+
+    void emitEndSampling(uint32_t index)
+    {
+        m_assembler.emitSampling(reinterpret_cast<void*>(&ARMProfiler::endSampling), index);
+    }
+#endif // ENABLE_PROFILE_ARM
+
 private:
     friend class LinkBuffer;
     friend class RepatchBuffer;
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
index cc3fb19..9637b6a 100644
--- a/JavaScriptCore/jit/JIT.cpp
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -43,6 +43,10 @@
 #include <stdio.h>
 #endif
 
+#ifdef ENABLE_PROFILE_ARM
+#include "ARMProfiler.h"
+#endif
+
 using namespace std;
 
 namespace JSC {
@@ -153,6 +157,22 @@ void JIT::privateCompileMainPass()
     m_globalResolveInfoIndex = 0;
     m_callLinkInfoIndex = 0;
 
+#if ENABLE_PROFILE_ARM
+    char* source = m_codeBlock->source()->url().ascii();
+    int sourceLen = strlen(source);
+    char offset[32];
+    sprintf(offset, "%d", m_codeBlock->sourceOffset());
+    int offsetLen = strlen(offset);
+    int len = sourceLen + offsetLen + 2;
+    char* m_functionName = (char*)malloc(len);
+    memmove(m_functionName, source, sourceLen);
+    m_functionName[sourceLen] = ':';
+    memmove(m_functionName + sourceLen + 1, offset, offsetLen + 1);
+
+    emitStartSampling(ARMProfiler::addProfileEvent(m_functionName, NULL));
+    ARMProfiler::autoFreeMemory(m_functionName);
+#endif
+
     for (m_bytecodeIndex = 0; m_bytecodeIndex < instructionCount; ) {
         Instruction* currentInstruction = instructionsBegin + m_bytecodeIndex;
         ASSERT_WITH_MESSAGE(m_interpreter->isOpcode(currentInstruction->u.opcode), "privateCompileMainPass gone bad @ %d", m_bytecodeIndex);
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index b669dfa..22b0438 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -65,6 +65,9 @@ void JIT::emit_op_end(Instruction* currentInstruction)
         JITStubCall(this, JITStubs::cti_op_end).call();
     ASSERT(returnValueRegister != callFrameRegister);
     emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
+#if ENABLE_PROFILE_ARM
+    emitEndSampling(ARMProfiler::StopSampling);
+#endif
     restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register))));
     ret();
 }
@@ -302,6 +305,10 @@ void JIT::emit_op_ret(Instruction* currentInstruction)
     // Restore our caller's "r".
     emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
 
+#if ENABLE_PROFILE_ARM
+    emitEndSampling(ARMProfiler::StopSampling);
+#endif
+
     // Return.
     restoreReturnAddressBeforeReturn(regT1);
     ret();
diff --git a/JavaScriptCore/jsc.cpp b/JavaScriptCore/jsc.cpp
index 769169b..076993b 100644
--- a/JavaScriptCore/jsc.cpp
+++ b/JavaScriptCore/jsc.cpp
@@ -63,6 +63,10 @@
 #include <QDateTime>
 #endif
 
+#ifdef ENABLE_PROFILE_ARM
+#include "ARMProfiler.h"
+#endif
+
 using namespace JSC;
 using namespace WTF;
 
@@ -560,6 +564,9 @@ int jscmain(int argc, char** argv, JSGlobalData* globalData)
     if (options.interactive && success)
         runInteractive(globalObject);
 
+#ifdef ENABLE_PROFILE_ARM
+    ARMProfiler::printProfile(stdout);
+#endif
     return success ? 0 : 3;
 }
 
-- 
1.6.0.4


