diff options
Diffstat (limited to 'Source/JavaScriptCore/bytecode/CallLinkStatus.cpp')
-rw-r--r-- | Source/JavaScriptCore/bytecode/CallLinkStatus.cpp | 96 |
1 files changed, 89 insertions, 7 deletions
diff --git a/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp b/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp index 7f9e9ee8a..509b15aaf 100644 --- a/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp +++ b/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,9 +28,59 @@ #include "CodeBlock.h" #include "LLIntCallLinkInfo.h" +#include "Operations.h" +#include <wtf/CommaPrinter.h> namespace JSC { +CallLinkStatus::CallLinkStatus(JSValue value) + : m_callTarget(value) + , m_executable(0) + , m_structure(0) + , m_couldTakeSlowPath(false) + , m_isProved(false) +{ + if (!value || !value.isCell()) + return; + + m_structure = value.asCell()->structure(); + + if (!value.asCell()->inherits(&JSFunction::s_info)) + return; + + m_executable = jsCast<JSFunction*>(value.asCell())->executable(); +} + +JSFunction* CallLinkStatus::function() const +{ + if (!m_callTarget || !m_callTarget.isCell()) + return 0; + + if (!m_callTarget.asCell()->inherits(&JSFunction::s_info)) + return 0; + + return jsCast<JSFunction*>(m_callTarget.asCell()); +} + +InternalFunction* CallLinkStatus::internalFunction() const +{ + if (!m_callTarget || !m_callTarget.isCell()) + return 0; + + if (!m_callTarget.asCell()->inherits(&InternalFunction::s_info)) + return 0; + + return jsCast<InternalFunction*>(m_callTarget.asCell()); +} + +Intrinsic CallLinkStatus::intrinsicFor(CodeSpecializationKind kind) const +{ + if (!m_executable) + return NoIntrinsic; + + return m_executable->intrinsicFor(kind); +} + CallLinkStatus CallLinkStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex) { UNUSED_PARAM(profiledBlock); @@ -39,9 +89,9 @@ CallLinkStatus CallLinkStatus::computeFromLLInt(CodeBlock* profiledBlock, unsign Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex; LLIntCallLinkInfo* callLinkInfo = instruction[4].u.callLinkInfo; - return CallLinkStatus(callLinkInfo->lastSeenCallee.get(), false); + return CallLinkStatus(callLinkInfo->lastSeenCallee.get()); #else - return CallLinkStatus(0, false); + return CallLinkStatus(); #endif } @@ -54,17 +104,49 @@ CallLinkStatus CallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned byt return computeFromLLInt(profiledBlock, bytecodeIndex); if (profiledBlock->couldTakeSlowCase(bytecodeIndex)) - return CallLinkStatus(0, true); + return CallLinkStatus::takesSlowPath(); - JSFunction* target = profiledBlock->getCallLinkInfo(bytecodeIndex).lastSeenCallee.get(); + CallLinkInfo& callLinkInfo = profiledBlock->getCallLinkInfo(bytecodeIndex); + if (callLinkInfo.stub) + return CallLinkStatus(callLinkInfo.stub->executable(), callLinkInfo.stub->structure()); + + JSFunction* target = callLinkInfo.lastSeenCallee.get(); if (!target) return computeFromLLInt(profiledBlock, bytecodeIndex); - return CallLinkStatus(target, false); + if (callLinkInfo.hasSeenClosure) + return CallLinkStatus(target->executable(), target->structure()); + + return CallLinkStatus(target); #else - return CallLinkStatus(0, false); + return CallLinkStatus(); #endif } +void CallLinkStatus::dump(PrintStream& out) const +{ + if (!isSet()) { + out.print("Not Set"); + return; + } + + CommaPrinter comma; + + if (m_isProved) + out.print(comma, "Statically Proved"); + + if (m_couldTakeSlowPath) + out.print(comma, "Could Take Slow Path"); + + if (m_callTarget) + out.print(comma, "Known target: ", m_callTarget); + + if (m_executable) + out.print(comma, "Executable/CallHash: ", RawPointer(m_executable), "/", m_executable->hashFor(CodeForCall)); + + if (m_structure) + out.print(comma, "Structure: ", RawPointer(m_structure)); +} + } // namespace JSC |