Chromium Code Reviews| Index: src/third_party/vtune/vtune-jit.cc |
| =================================================================== |
| --- src/third_party/vtune/vtune-jit.cc (revision 0) |
| +++ src/third_party/vtune/vtune-jit.cc (revision 0) |
| @@ -0,0 +1,299 @@ |
| +/* |
| + This file is provided under a dual BSD/GPLv2 license. When using or |
| + redistributing this file, you may do so under either license. |
| + |
| + GPL LICENSE SUMMARY |
| + |
| + Copyright(c) 2005-2012 Intel Corporation. All rights reserved. |
| + |
| + This program is free software; you can redistribute it and/or modify |
| + it under the terms of version 2 of the GNU General Public License as |
| + published by the Free Software Foundation. |
| + |
| + This program is distributed in the hope that it will be useful, but |
| + WITHOUT ANY WARRANTY; without even the implied warranty of |
| + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + General Public License for more details. |
| + |
| + You should have received a copy of the GNU General Public License |
| + along with this program; if not, write to the Free Software |
| + Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
| + The full GNU General Public License is included in this distribution |
| + in the file called LICENSE.GPL. |
| + |
| + Contact Information: |
| + http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/ |
| + |
| + BSD LICENSE |
| + |
| + Copyright(c) 2005-2012 Intel Corporation. All rights reserved. |
| + All rights reserved. |
| + |
| + Redistribution and use in source and binary forms, with or without |
| + modification, are permitted provided that the following conditions |
| + are met: |
| + |
| + * Redistributions of source code must retain the above copyright |
| + notice, this list of conditions and the following disclaimer. |
| + * 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. |
| + * Neither the name of Intel Corporation nor the names of its |
| + contributors may be used to endorse or promote products derived |
| + from this software without specific prior written permission. |
| + |
| + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| + "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 THE COPYRIGHT |
| + OWNER 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 <string.h> |
| + |
| +#include "third_party/vtune/v8-vtune.h" |
| +#include "third_party/vtune/vtune-jit.h" |
| + |
| +namespace vTune { |
| +namespace internal { |
| + |
| + |
| +// This class is used to record the JITted code position info for JIT |
| +// code profiling. |
| +class JITCodeLineInfo : public Malloced { |
| + public: |
| + JITCodeLineInfo() : line_num_info_(10) { } |
| + |
| + void SetPosition(intptr_t pc, int pos) { |
| + AddCodeLineInfo(LineNumInfo(pc, pos)); |
| + } |
| + |
| + struct LineNumInfo { |
| + LineNumInfo(intptr_t pc, int pos) |
| + : pc_(pc), pos_(pos) { } |
| + |
| + intptr_t pc_; |
| + int pos_; |
| + }; |
| + |
| + List<LineNumInfo>* GetLineNumInfo() { |
| + return &line_num_info_; |
| + } |
| + |
| + private: |
| + void AddCodeLineInfo(const LineNumInfo& line_info) { |
| + line_num_info_.Add(line_info); |
| + } |
| + List<LineNumInfo> line_num_info_; |
| +}; |
| + |
| +Mutex* VTUNEJITInterface::vtunemutex_ = OS::CreateMutex(); |
| + |
| +static bool SameCodeObjects(void* key1, void* key2) { |
| + return key1 == key2; |
| +} |
| + |
| +static HashMap* GetEntries() { |
| + static HashMap* entries; |
| + if (entries == NULL) { |
| + entries = new HashMap(&SameCodeObjects); |
| + } |
| + return entries; |
| +} |
| + |
| +static uint32_t HashForCodeObject(void* code) { |
| + static const uintptr_t kGoldenRatio = 2654435761u; |
| + uintptr_t hash = reinterpret_cast<uintptr_t>(code); |
| + return static_cast<uint32_t>(hash * kGoldenRatio); |
| +} |
| + |
| + |
| +static const intptr_t kLineInfoTag = 0x1; |
| + |
| +static bool IsSourceInfoAvailable(Handle<Script> script) { |
| + return !script.is_null() && |
| + script->source()->IsString() && |
| + script->HasValidSource() && |
| + script->name()->IsString(); |
| +} |
| + |
| +static bool IsLineInfoTagged(void* ptr) { |
| + return 0 != (reinterpret_cast<intptr_t>(ptr)); |
| +} |
| + |
| +static void* TagLineInfo(JITCodeLineInfo* ptr) { |
| + return reinterpret_cast<void*>(reinterpret_cast<intptr_t>(ptr)); |
| +} |
| + |
| +static JITCodeLineInfo* UntagLineInfo(void* ptr) { |
| + return reinterpret_cast<JITCodeLineInfo*>( |
| + reinterpret_cast<intptr_t>(ptr)); |
| +} |
| + |
| +// The parameter str is a mixed pattern which contains the |
| +// function name and some other info. It comes from all the |
| +// Logger::CodeCreateEvent(...) function. This funtion get the |
| +// pure function name from the input parameter. |
| +static char* GetFunctionNameFromMixedName(const char* str, int length) { |
| + int index = 0; |
| + int count = 0; |
| + char* start_ptr = NULL; |
| + |
| + while (str[index++] != ':' && (index < length)) {} |
| + |
| + if (str[index] == '*' || str[index] == '~' ) index++; |
| + if (index >= length) return NULL; |
| + |
| + start_ptr = const_cast<char*>(str + index); |
| + |
| + while (index < length && str[index++] != ' ') { |
| + count++; |
| + } |
| + |
| + char* result = NewArray<char>(count + 1); |
| + memcpy(result, start_ptr, count); |
| + result[count] = '\0'; |
| + |
| + return result; |
| +} |
| + |
| +// The JitCodeEventHandler for Vtune. |
| +void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) { |
| + CHECK(event != NULL); |
| + |
| + if (VTUNERUNNING) { |
| + switch (event->type) { |
| + case v8::JitCodeEvent::CODE_ADDED: { |
| + ScopedLock lock(vtunemutex_); |
| + |
| + char* temp_file_name = NULL; |
| + char* temp_method_name = |
| + GetFunctionNameFromMixedName(event->name.str, |
| + static_cast<int>(event->name.len)); |
| + iJIT_Method_Load jmethod; |
| + memset(&jmethod, 0, sizeof jmethod); |
| + jmethod.method_id = iJIT_GetNewMethodID(); |
| + jmethod.method_load_address = event->code_start; |
| + jmethod.method_size = static_cast<unsigned int>(event->code_len); |
| + jmethod.method_name = temp_method_name; |
| + |
| + Script** script_handler = |
| + reinterpret_cast<v8::internal::Script**>(*event->script); |
|
danno
2013/03/27 12:33:48
You should at no point access anything in the v8::
|
| + if (script_handler != NULL) { |
| + Script* script = *script_handler; |
| + |
| + if (script != NULL && script->name()->IsString()) { |
| + // Get the source file name and set it to jmethod.source_file_name |
| + Handle<String> filename = |
| + Handle<String>(String::cast(script->name())); |
| + SmartArrayPointer<char> filename_cstring = |
| + filename->ToCString(DISALLOW_NULLS); |
| + |
| + size_t str_length = strlen(*filename_cstring); |
| + temp_file_name = NewArray<char>(str_length + 1); |
| + memcpy(temp_file_name, *filename_cstring, str_length +1); |
| + |
| + jmethod.source_file_name = temp_file_name; |
| + |
| + HashMap::Entry* entry = |
| + GetEntries()->Lookup(event->code_start, |
| + HashForCodeObject(event->code_start), |
| + false); |
| + |
| + if (entry != NULL && IsLineInfoTagged(entry->value) |
| + && IsSourceInfoAvailable(Handle<Script>(script))) { |
| + // Get the line_num_info and set it to jmethod.line_number_table |
| + GetScriptLineNumber(Handle<Script>(script), 0); |
| + JITCodeLineInfo* line_info = UntagLineInfo(entry->value); |
| + List<JITCodeLineInfo::LineNumInfo>* vtunelineinfo = |
| + line_info->GetLineNumInfo(); |
| + |
| + jmethod.line_number_size = vtunelineinfo->length(); |
| + jmethod.line_number_table = |
| + reinterpret_cast<LineNumberInfo*>( |
| + malloc(sizeof(LineNumberInfo)*jmethod.line_number_size)); |
| + // populate the lineinfo for the code. Filter it before |
| + for (int e = 0; e < vtunelineinfo->length(); e++) { |
| + JITCodeLineInfo::LineNumInfo line_info = vtunelineinfo->at(e); |
| + jmethod.line_number_table[e].Offset = |
| + static_cast<unsigned int>(line_info.pc_); |
| + jmethod.line_number_table[e].LineNumber = |
| + GetScriptLineNumberSafe( |
| + Handle<Script>(script), line_info.pos_)+1; |
| + } |
| + delete line_info; |
| + } |
| + GetEntries()->Remove(event->code_start, |
| + HashForCodeObject(event->code_start)); |
| +#ifdef DEBUG |
| + PrintF("Filename: %s, MethodName: %s\n", |
| + jmethod.source_file_name, |
| + jmethod.method_name); |
| +#endif |
| + } |
| + } |
| + |
| + iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, |
| + reinterpret_cast<void*>(&jmethod)); |
| + DeleteArray(temp_method_name); |
| + DeleteArray(temp_file_name); |
| + break; |
| + } |
| + // TODO(chunyang.dai@intel.com): code_move will be supported. |
| + case v8::JitCodeEvent::CODE_MOVED: |
| + break; |
| + // Currently the CODE_REMOVED event is not issued. |
| + case v8::JitCodeEvent::CODE_REMOVED: |
| + break; |
| + case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: { |
| + JITCodeLineInfo* line_info = |
| + reinterpret_cast<JITCodeLineInfo*>(event->user_data); |
| + if (line_info != NULL) { |
| + line_info->SetPosition(static_cast<intptr_t>(event->line_info.offset), |
| + static_cast<int>(event->line_info.pos)); |
| + } |
| + break; |
| + } |
| + case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: { |
| + v8::JitCodeEvent* temp_event = const_cast<v8::JitCodeEvent*>(event); |
| + temp_event->user_data = new JITCodeLineInfo(); |
| + break; |
| + } |
| + case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: { |
| + ScopedLock lock(vtunemutex_); |
| + HashMap::Entry* entry = |
| + GetEntries()->Lookup(event->code_start, |
| + HashForCodeObject(event->code_start), |
| + true); |
| + |
| + ASSERT(entry->value == NULL); |
| + entry->value = |
| + TagLineInfo(reinterpret_cast<JITCodeLineInfo*>(event->user_data)); |
| + break; |
| + } |
| + default: |
| + CHECK(false); |
| + break; |
| + } |
| + } |
| + return; |
| +} |
| + |
| +} // namespace internal |
| + |
| +void InitilizeVtuneForV8() { |
| + if (v8::V8::Initialize()) { |
| + v8::V8::SetFlagsFromString("--nocompact_code_space", |
| + i::StrLength("--nocompact_code_space")); |
| + v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, |
| + vTune::internal::VTUNEJITInterface::event_handler); |
| + } |
| +} |
| + |
| +} // namespace vTune |