Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (120896 => 120897)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2012-06-21 01:38:49 UTC (rev 120897)
@@ -54,6 +54,7 @@
bytecode/PolymorphicPutByIdList.cpp
bytecode/SpeculatedType.cpp
bytecode/PutByIdStatus.cpp
+ bytecode/ResolveGlobalStatus.cpp
bytecode/SamplingTool.cpp
bytecode/StructureStubInfo.cpp
bytecode/Watchpoint.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (120896 => 120897)
--- trunk/Source/_javascript_Core/ChangeLog 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-06-21 01:38:49 UTC (rev 120897)
@@ -1,5 +1,70 @@
2012-06-20 Filip Pizlo <[email protected]>
+ DFG should optimize ResolveGlobal
+ https://bugs.webkit.org/show_bug.cgi?id=89617
+
+ Reviewed by Oliver Hunt.
+
+ This adds inlining of ResolveGlobal accesses that are known monomorphic. It also
+ adds the specific function optimization to ResolveGlobal, when it is inlined. And,
+ it makes internal functions act like specific functions, since that will be the
+ most common use-case of this optimization.
+
+ This is only a slighy speed-up (sub 1%), since we don't yet do the obvious thing
+ with this optimization, which is to completely inline common "globally resolved"
+ function and constructor calls, like "new Array()".
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * _javascript_Core.vcproj/_javascript_Core/_javascript_Core.def:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::globalResolveInfoForBytecodeOffset):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::numberOfGlobalResolveInfos):
+ * bytecode/GlobalResolveInfo.h:
+ (JSC::getGlobalResolveInfoBytecodeOffset):
+ (JSC):
+ * bytecode/ResolveGlobalStatus.cpp: Added.
+ (JSC):
+ (JSC::computeForStructure):
+ (JSC::computeForLLInt):
+ (JSC::ResolveGlobalStatus::computeFor):
+ * bytecode/ResolveGlobalStatus.h: Added.
+ (JSC):
+ (ResolveGlobalStatus):
+ (JSC::ResolveGlobalStatus::ResolveGlobalStatus):
+ (JSC::ResolveGlobalStatus::state):
+ (JSC::ResolveGlobalStatus::isSet):
+ (JSC::ResolveGlobalStatus::operator!):
+ (JSC::ResolveGlobalStatus::isSimple):
+ (JSC::ResolveGlobalStatus::takesSlowPath):
+ (JSC::ResolveGlobalStatus::structure):
+ (JSC::ResolveGlobalStatus::offset):
+ (JSC::ResolveGlobalStatus::specificValue):
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::handleGetByOffset):
+ (DFG):
+ (JSC::DFG::ByteCodeParser::handleGetById):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * runtime/JSObject.cpp:
+ (JSC::getCallableObjectSlow):
+ (JSC):
+ (JSC::JSObject::put):
+ (JSC::JSObject::putDirectVirtual):
+ (JSC::JSObject::putDirectAccessor):
+ * runtime/JSObject.h:
+ (JSC):
+ (JSC::getCallableObject):
+ (JSC::JSObject::putOwnDataProperty):
+ (JSC::JSObject::putDirect):
+ (JSC::JSObject::putDirectWithoutTransition):
+
+2012-06-20 Filip Pizlo <[email protected]>
+
Functions on global objects should be specializable
https://bugs.webkit.org/show_bug.cgi?id=89615
Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (120896 => 120897)
--- trunk/Source/_javascript_Core/GNUmakefile.list.am 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am 2012-06-21 01:38:49 UTC (rev 120897)
@@ -126,6 +126,8 @@
Source/_javascript_Core/bytecode/PutByIdStatus.cpp \
Source/_javascript_Core/bytecode/PutByIdStatus.h \
Source/_javascript_Core/bytecode/PutKind.h \
+ Source/_javascript_Core/bytecode/ResolveGlobalStatus.cpp \
+ Source/_javascript_Core/bytecode/ResolveGlobalStatus.h \
Source/_javascript_Core/bytecode/SamplingTool.cpp \
Source/_javascript_Core/bytecode/SamplingTool.h \
Source/_javascript_Core/bytecode/StructureSet.h \
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (120896 => 120897)
--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2012-06-21 01:38:49 UTC (rev 120897)
@@ -189,6 +189,7 @@
?get@Structure@JSC@@QAEIAAVJSGlobalData@2@VPropertyName@2@AAIAAPAVJSCell@2@@Z
?getCalculatedDisplayName@JSC@@YA?AVUString@1@PAVExecState@1@PAVJSObject@1@@Z
?getCallData@JSCell@JSC@@SA?AW4CallType@2@PAV12@AATCallData@2@@Z
+ ?getCallableObjectSlow@JSC@@YAPAVJSCell@1@PAV21@@Z
?getConstructData@JSCell@JSC@@SA?AW4ConstructType@2@PAV12@AATConstructData@2@@Z
?getCurrentLocalTime@WTF@@YAXPAUtm@@@Z
?getObject@JSCell@JSC@@QAEPAVJSObject@2@XZ
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (120896 => 120897)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2012-06-21 01:38:49 UTC (rev 120897)
@@ -211,6 +211,8 @@
0FF4275715914A20004CB9FF /* LinkBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4275615914A20004CB9FF /* LinkBuffer.cpp */; };
0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */; };
0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF427621591A1C9004CB9FF /* DFGDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF42771159275D5004CB9FF /* ResolveGlobalStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */; };
+ 0FF42772159275D8004CB9FF /* ResolveGlobalStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
@@ -933,6 +935,8 @@
0FF4275615914A20004CB9FF /* LinkBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinkBuffer.cpp; sourceTree = "<group>"; };
0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDisassembler.cpp; path = dfg/DFGDisassembler.cpp; sourceTree = "<group>"; };
0FF427621591A1C9004CB9FF /* DFGDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDisassembler.h; path = dfg/DFGDisassembler.h; sourceTree = "<group>"; };
+ 0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResolveGlobalStatus.cpp; sourceTree = "<group>"; };
+ 0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResolveGlobalStatus.h; 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>"; };
@@ -2347,6 +2351,8 @@
0F93329814CA7DC10085F3C6 /* MethodCallLinkStatus.h */,
0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */,
0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */,
+ 0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */,
+ 0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */,
0F93329B14CA7DC10085F3C6 /* StructureSet.h */,
0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */,
0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */,
@@ -2766,6 +2772,7 @@
0FF42749158EBE91004CB9FF /* udis86_types.h in Headers */,
0FF4274B158EBE91004CB9FF /* udis86.h in Headers */,
0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */,
+ 0FF42772159275D8004CB9FF /* ResolveGlobalStatus.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3353,6 +3360,7 @@
0FF4275715914A20004CB9FF /* LinkBuffer.cpp in Sources */,
C2D58C3415912FEE0021A844 /* GCActivityCallback.cpp in Sources */,
0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */,
+ 0FF42771159275D5004CB9FF /* ResolveGlobalStatus.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: trunk/Source/_javascript_Core/Target.pri (120896 => 120897)
--- trunk/Source/_javascript_Core/Target.pri 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/Target.pri 2012-06-21 01:38:49 UTC (rev 120897)
@@ -64,6 +64,7 @@
bytecode/Opcode.cpp \
bytecode/PolymorphicPutByIdList.cpp \
bytecode/PutByIdStatus.cpp \
+ bytecode/ResolveGlobalStatus.cpp \
bytecode/SamplingTool.cpp \
bytecode/SpeculatedType.cpp \
bytecode/StructureStubInfo.cpp \
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (120896 => 120897)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2012-06-21 01:38:49 UTC (rev 120897)
@@ -2258,6 +2258,10 @@
return false;
return true;
}
+GlobalResolveInfo& CodeBlock::globalResolveInfoForBytecodeOffset(unsigned bytecodeOffset)
+{
+ return *(binarySearch<GlobalResolveInfo, unsigned, getGlobalResolveInfoBytecodeOffset>(m_globalResolveInfos.begin(), m_globalResolveInfos.size(), bytecodeOffset));
+}
#endif
void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (120896 => 120897)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-06-21 01:38:49 UTC (rev 120897)
@@ -553,6 +553,8 @@
}
GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);
+ GlobalResolveInfo& globalResolveInfoForBytecodeOffset(unsigned bytecodeOffset);
+ unsigned numberOfGlobalResolveInfos() { return m_globalResolveInfos.size(); }
void setNumberOfCallLinkInfos(size_t size) { m_callLinkInfos.grow(size); }
size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); }
Modified: trunk/Source/_javascript_Core/bytecode/GlobalResolveInfo.h (120896 => 120897)
--- trunk/Source/_javascript_Core/bytecode/GlobalResolveInfo.h 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/bytecode/GlobalResolveInfo.h 2012-06-21 01:38:49 UTC (rev 120897)
@@ -42,6 +42,11 @@
unsigned bytecodeOffset;
};
+inline unsigned getGlobalResolveInfoBytecodeOffset(GlobalResolveInfo* globalResolveInfo)
+{
+ return globalResolveInfo->bytecodeOffset;
+}
+
} // namespace JSC
#endif // GlobalResolveInfo_h
Added: trunk/Source/_javascript_Core/bytecode/ResolveGlobalStatus.cpp (0 => 120897)
--- trunk/Source/_javascript_Core/bytecode/ResolveGlobalStatus.cpp (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/ResolveGlobalStatus.cpp 2012-06-21 01:38:49 UTC (rev 120897)
@@ -0,0 +1,88 @@
+/*
+ * 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 "ResolveGlobalStatus.h"
+
+#include "CodeBlock.h"
+#include "JSValue.h"
+#include "Structure.h"
+
+namespace JSC {
+
+static ResolveGlobalStatus computeForStructure(CodeBlock* codeBlock, Structure* structure, Identifier& identifier)
+{
+ unsigned attributesIgnored;
+ JSCell* specificValue;
+ size_t offset = structure->get(
+ *codeBlock->globalData(), identifier, attributesIgnored, specificValue);
+ if (offset == notFound)
+ return ResolveGlobalStatus();
+
+ return ResolveGlobalStatus(ResolveGlobalStatus::Simple, structure, offset, specificValue);
+}
+
+static ResolveGlobalStatus computeForLLInt(CodeBlock* codeBlock, unsigned bytecodeIndex, Identifier& identifier)
+{
+#if ENABLE(LLINT)
+ Instruction* instruction = codeBlock->instructions().begin() + bytecodeIndex;
+
+ ASSERT(instruction[0].u.opcode == llint_op_resolve_global);
+
+ Structure* structure = instruction[3].u.structure.get();
+ if (!structure)
+ return ResolveGlobalStatus();
+
+ return computeForStructure(codeBlock, structure, identifier);
+#else
+ UNUSED_PARAM(codeBlock);
+ UNUSED_PARAM(bytecodeIndex);
+ UNUSED_PARAM(identifier);
+ return ResolveGlobalStatus();
+#endif
+}
+
+ResolveGlobalStatus ResolveGlobalStatus::computeFor(CodeBlock* codeBlock, unsigned bytecodeIndex, Identifier& identifier)
+{
+#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
+ if (!codeBlock->numberOfGlobalResolveInfos())
+ return computeForLLInt(codeBlock, bytecodeIndex, identifier);
+
+ if (codeBlock->likelyToTakeSlowCase(bytecodeIndex))
+ return ResolveGlobalStatus(TakesSlowPath);
+
+ GlobalResolveInfo& globalResolveInfo = codeBlock->globalResolveInfoForBytecodeOffset(bytecodeIndex);
+
+ if (!globalResolveInfo.structure)
+ return computeForLLInt(codeBlock, bytecodeIndex, identifier);
+
+ return computeForStructure(codeBlock, globalResolveInfo.structure.get(), identifier);
+#else
+ return computeForLLInt(codeBlock, bytecodeIndex, identifier);
+#endif
+}
+
+} // namespace JSC
+
Added: trunk/Source/_javascript_Core/bytecode/ResolveGlobalStatus.h (0 => 120897)
--- trunk/Source/_javascript_Core/bytecode/ResolveGlobalStatus.h (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/ResolveGlobalStatus.h 2012-06-21 01:38:49 UTC (rev 120897)
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+#ifndef ResolveGlobalStatus_h
+#define ResolveGlobalStatus_h
+
+#include "JSValue.h"
+#include <wtf/NotFound.h>
+
+namespace JSC {
+
+class CodeBlock;
+class Identifier;
+class Structure;
+
+class ResolveGlobalStatus {
+public:
+ enum State {
+ NoInformation,
+ Simple,
+ TakesSlowPath
+ };
+
+ ResolveGlobalStatus()
+ : m_state(NoInformation)
+ , m_structure(0)
+ , m_offset(notFound)
+ {
+ }
+
+ ResolveGlobalStatus(
+ State state, Structure* structure = 0, size_t offset = notFound,
+ JSValue specificValue = JSValue())
+ : m_state(state)
+ , m_structure(structure)
+ , m_offset(offset)
+ , m_specificValue(specificValue)
+ {
+ }
+
+ static ResolveGlobalStatus computeFor(CodeBlock*, unsigned bytecodeIndex, Identifier&);
+
+ State state() const { return m_state; }
+
+ bool isSet() const { return m_state != NoInformation; }
+ bool operator!() const { return !isSet(); }
+ bool isSimple() const { return m_state == Simple; }
+ bool takesSlowPath() const { return m_state == TakesSlowPath; }
+
+ Structure* structure() const { return m_structure; }
+ size_t offset() const { return m_offset; }
+ JSValue specificValue() const { return m_specificValue; }
+
+private:
+ State m_state;
+ Structure* m_structure;
+ size_t m_offset;
+ JSValue m_specificValue;
+}; // class ResolveGlobalStatus
+
+} // namespace JSC
+
+#endif // ResolveGlobalStatus_h
+
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (120896 => 120897)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2012-06-21 01:38:49 UTC (rev 120897)
@@ -35,6 +35,7 @@
#include "GetByIdStatus.h"
#include "MethodCallLinkStatus.h"
#include "PutByIdStatus.h"
+#include "ResolveGlobalStatus.h"
#include <wtf/HashMap.h>
#include <wtf/MathExtras.h>
@@ -94,6 +95,9 @@
void setIntrinsicResult(bool usesResult, int resultOperand, NodeIndex);
// Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
bool handleIntrinsic(bool usesResult, int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction);
+ void handleGetByOffset(
+ int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
+ bool useInlineStorage, size_t offset);
void handleGetById(
int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
const GetByIdStatus&);
@@ -1567,6 +1571,31 @@
}
}
+void ByteCodeParser::handleGetByOffset(
+ int destinationOperand, SpeculatedType prediction, NodeIndex base, unsigned identifierNumber,
+ bool useInlineStorage, size_t offset)
+{
+ NodeIndex propertyStorage;
+ size_t offsetOffset;
+ if (useInlineStorage) {
+ propertyStorage = base;
+ ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
+ offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
+ } else {
+ propertyStorage = addToGraph(GetPropertyStorage, base);
+ offsetOffset = 0;
+ }
+ set(destinationOperand,
+ addToGraph(
+ GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction),
+ propertyStorage));
+
+ StorageAccessData storageAccessData;
+ storageAccessData.offset = offset + offsetOffset;
+ storageAccessData.identifierNumber = identifierNumber;
+ m_graph.m_storageAccessData.append(storageAccessData);
+}
+
void ByteCodeParser::handleGetById(
int destinationOperand, SpeculatedType prediction, NodeIndex base, unsigned identifierNumber,
const GetByIdStatus& getByIdStatus)
@@ -1620,25 +1649,9 @@
return;
}
- NodeIndex propertyStorage;
- size_t offsetOffset;
- if (useInlineStorage) {
- propertyStorage = base;
- ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
- offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
- } else {
- propertyStorage = addToGraph(GetPropertyStorage, base);
- offsetOffset = 0;
- }
- set(destinationOperand,
- addToGraph(
- GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction),
- propertyStorage));
-
- StorageAccessData storageAccessData;
- storageAccessData.offset = getByIdStatus.offset() + offsetOffset;
- storageAccessData.identifierNumber = identifierNumber;
- m_graph.m_storageAccessData.append(storageAccessData);
+ handleGetByOffset(
+ destinationOperand, prediction, base, identifierNumber, useInlineStorage,
+ getByIdStatus.offset());
}
void ByteCodeParser::prepareToParseBlock()
@@ -2648,10 +2661,39 @@
case op_resolve_global: {
SpeculatedType prediction = getPrediction();
+ unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[
+ currentInstruction[2].u.operand];
+
+ ResolveGlobalStatus status = ResolveGlobalStatus::computeFor(
+ m_inlineStackTop->m_profiledBlock, m_currentIndex,
+ m_codeBlock->identifier(identifierNumber));
+ if (status.isSimple()) {
+ ASSERT(status.structure());
+
+ NodeIndex globalObject = addStructureTransitionCheck(
+ m_inlineStackTop->m_codeBlock->globalObject(), status.structure());
+
+ if (status.specificValue()) {
+ ASSERT(status.specificValue().isCell());
+
+ set(currentInstruction[1].u.operand,
+ cellConstant(status.specificValue().asCell()));
+ } else {
+ handleGetByOffset(
+ currentInstruction[1].u.operand, prediction, globalObject,
+ identifierNumber, status.structure()->isUsingInlineStorage(),
+ status.offset());
+ }
+
+ m_globalResolveNumber++; // Skip over the unused global resolve info.
+
+ NEXT_OPCODE(op_resolve_global);
+ }
+
NodeIndex resolve = addToGraph(ResolveGlobal, OpInfo(m_graph.m_resolveGlobalData.size()), OpInfo(prediction));
m_graph.m_resolveGlobalData.append(ResolveGlobalData());
ResolveGlobalData& data = ""
- data.identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
+ data.identifierNumber = identifierNumber;
data.resolveInfoIndex = m_globalResolveNumber++;
set(currentInstruction[1].u.operand, resolve);
Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (120896 => 120897)
--- trunk/Source/_javascript_Core/runtime/JSObject.cpp 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp 2012-06-21 01:38:49 UTC (rev 120897)
@@ -43,6 +43,16 @@
namespace JSC {
+JSCell* getCallableObjectSlow(JSCell* cell)
+{
+ Structure* structure = cell->structure();
+ if (structure->typeInfo().type() == JSFunctionType)
+ return cell;
+ if (structure->classInfo()->isSubClassOf(&InternalFunction::s_info))
+ return cell;
+ return 0;
+}
+
ASSERT_CLASS_FITS_IN_CELL(JSObject);
ASSERT_CLASS_FITS_IN_CELL(JSNonFinalObject);
ASSERT_CLASS_FITS_IN_CELL(JSFinalObject);
@@ -133,7 +143,7 @@
for (JSObject* obj = thisObject; !obj->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) {
prototype = obj->prototype();
if (prototype.isNull()) {
- if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value)) && slot.isStrictMode())
+ if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode())
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
@@ -180,7 +190,7 @@
break;
}
- if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value)) && slot.isStrictMode())
+ if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode())
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
@@ -196,7 +206,7 @@
{
ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
PutPropertySlot slot;
- object->putDirectInternal<PutModeDefineOwnProperty>(exec->globalData(), propertyName, value, attributes, slot, getJSFunction(value));
+ object->putDirectInternal<PutModeDefineOwnProperty>(exec->globalData(), propertyName, value, attributes, slot, getCallableObject(value));
}
bool JSObject::setPrototypeWithCycleCheck(JSGlobalData& globalData, JSValue prototype)
@@ -226,7 +236,7 @@
ASSERT(value.isGetterSetter() && (attributes & Accessor));
PutPropertySlot slot;
- putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getJSFunction(value));
+ putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getCallableObject(value));
// putDirect will change our Structure if we add a new property. For
// getters and setters, though, we also need to change our Structure
Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (120896 => 120897)
--- trunk/Source/_javascript_Core/runtime/JSObject.h 2012-06-21 01:34:11 UTC (rev 120896)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h 2012-06-21 01:38:49 UTC (rev 120897)
@@ -46,6 +46,15 @@
return 0;
}
+ JS_EXPORT_PRIVATE JSCell* getCallableObjectSlow(JSCell*);
+
+ inline JSCell* getCallableObject(JSValue value)
+ {
+ if (!value.isCell())
+ return 0;
+ return getCallableObjectSlow(value.asCell());
+ }
+
class GetterSetter;
class HashEntry;
class InternalFunction;
@@ -759,20 +768,20 @@
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
ASSERT(!structure()->hasGetterSetterProperties());
- return putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value));
+ return putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value));
}
inline void JSObject::putDirect(JSGlobalData& globalData, PropertyName propertyName, JSValue value, unsigned attributes)
{
ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
PutPropertySlot slot;
- putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getJSFunction(value));
+ putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getCallableObject(value));
}
inline void JSObject::putDirect(JSGlobalData& globalData, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(!value.isGetterSetter());
- putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, 0, slot, getJSFunction(value));
+ putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, 0, slot, getCallableObject(value));
}
inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, PropertyName propertyName, JSValue value, unsigned attributes)
@@ -781,7 +790,7 @@
PropertyStorage newStorage = propertyStorage();
if (structure()->shouldGrowPropertyStorage())
newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize());
- size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getJSFunction(value));
+ size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getCallableObject(value));
setPropertyStorage(globalData, newStorage, structure());
putDirectOffset(globalData, offset, value);
}