Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (119778 => 119779)
--- trunk/Source/_javascript_Core/ChangeLog 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-06-08 01:31:21 UTC (rev 119779)
@@ -1,3 +1,45 @@
+2012-06-07 Filip Pizlo <[email protected]>
+
+ DFG should inline prototype chain accesses, and do the right things if the
+ specific function optimization is available
+ https://bugs.webkit.org/show_bug.cgi?id=88594
+
+ Reviewed by Gavin Barraclough.
+
+ Looks like a 3% win on V8.
+
+ * bytecode/CodeBlock.h:
+ (JSC::Structure::prototypeForLookup):
+ (JSC):
+ * bytecode/GetByIdStatus.cpp:
+ (JSC::GetByIdStatus::computeFromLLInt):
+ (JSC):
+ (JSC::GetByIdStatus::computeForChain):
+ (JSC::GetByIdStatus::computeFor):
+ * bytecode/GetByIdStatus.h:
+ (JSC::GetByIdStatus::GetByIdStatus):
+ (JSC::GetByIdStatus::isSimple):
+ (JSC::GetByIdStatus::chain):
+ (JSC::GetByIdStatus::specificValue):
+ (GetByIdStatus):
+ * bytecode/StructureSet.h:
+ (StructureSet):
+ (JSC::StructureSet::singletonStructure):
+ * bytecode/StructureStubInfo.h:
+ (JSC::StructureStubInfo::initGetByIdProto):
+ (JSC::StructureStubInfo::initGetByIdChain):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleGetById):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCacheGetByID):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::tryCacheGetByID):
+ * runtime/JSGlobalObject.h:
+ (JSC::Structure::prototypeForLookup):
+ (JSC):
+ * runtime/Structure.h:
+ (Structure):
+
2012-06-07 Gavin Barraclough <[email protected]>
Math.pow on iOS does not support denormal numbers.
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (119778 => 119779)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2012-06-08 01:31:21 UTC (rev 119779)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
@@ -1499,6 +1499,11 @@
}
#endif
+ inline JSValue Structure::prototypeForLookup(CodeBlock* codeBlock) const
+ {
+ return prototypeForLookup(codeBlock->globalObject());
+ }
+
} // namespace JSC
#endif // CodeBlock_h
Modified: trunk/Source/_javascript_Core/bytecode/GetByIdStatus.cpp (119778 => 119779)
--- trunk/Source/_javascript_Core/bytecode/GetByIdStatus.cpp 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/bytecode/GetByIdStatus.cpp 2012-06-08 01:31:21 UTC (rev 119779)
@@ -44,18 +44,64 @@
Structure* structure = instruction[4].u.structure.get();
if (!structure)
- return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
+ return GetByIdStatus(NoInformation, false);
- size_t offset = structure->get(*profiledBlock->globalData(), ident);
+ unsigned attributesIgnored;
+ JSCell* specificValue;
+ size_t offset = structure->get(
+ *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
if (offset == notFound)
- return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
+ return GetByIdStatus(NoInformation, false);
- return GetByIdStatus(SimpleDirect, StructureSet(structure), offset, false);
+ return GetByIdStatus(Simple, false, StructureSet(structure), offset, specificValue);
#else
- return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
+ return GetByIdStatus(NoInformation, false);
#endif
}
+void GetByIdStatus::computeForChain(GetByIdStatus& result, CodeBlock* profiledBlock, Identifier& ident, Structure* structure)
+{
+#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
+ // Validate the chain. If the chain is invalid, then currently the best thing
+ // we can do is to assume that TakesSlow is true. In the future, it might be
+ // worth exploring reifying the structure chain from the structure we've got
+ // instead of using the one from the cache, since that will do the right things
+ // if the structure chain has changed. But that may be harder, because we may
+ // then end up having a different type of access altogether. And it currently
+ // does not appear to be worth it to do so -- effectively, the heuristic we
+ // have now is that if the structure chain has changed between when it was
+ // cached on in the baseline JIT and when the DFG tried to inline the access,
+ // then we fall back on a polymorphic access.
+ Structure* currentStructure = structure;
+ JSObject* currentObject = 0;
+ for (unsigned i = 0; i < result.m_chain.size(); ++i) {
+ currentObject = asObject(currentStructure->prototypeForLookup(profiledBlock));
+ currentStructure = result.m_chain[i];
+ if (currentObject->structure() != currentStructure)
+ return;
+ }
+
+ ASSERT(currentObject);
+
+ unsigned attributesIgnored;
+ JSCell* specificValue;
+
+ result.m_offset = currentStructure->get(
+ *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
+ if (result.m_offset == notFound)
+ return;
+
+ result.m_structureSet.add(structure);
+ result.m_specificValue = JSValue(specificValue);
+#else
+ UNUSED_PARAM(result);
+ UNUSED_PARAM(profiledBlock);
+ UNUSED_PARAM(ident);
+ UNUSED_PARAM(structure);
+ ASSERT_NOT_REACHED();
+#endif
+}
+
GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident)
{
UNUSED_PARAM(profiledBlock);
@@ -89,12 +135,12 @@
}
for (int i = 0; i < listSize; ++i) {
if (!list->list[i].isDirect)
- return GetByIdStatus(MakesCalls, StructureSet(), notFound, true);
+ return GetByIdStatus(MakesCalls, true);
}
// Next check if it takes slow case, in which case we want to be kind of careful.
if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex))
- return GetByIdStatus(TakesSlowPath, StructureSet(), notFound, true);
+ return GetByIdStatus(TakesSlowPath, true);
// Finally figure out if we can derive an access strategy.
GetByIdStatus result;
@@ -105,10 +151,15 @@
case access_get_by_id_self: {
Structure* structure = stubInfo.u.getByIdSelf.baseObjectStructure.get();
- result.m_offset = structure->get(*profiledBlock->globalData(), ident);
+ unsigned attributesIgnored;
+ JSCell* specificValue;
+ result.m_offset = structure->get(
+ *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
- if (result.m_offset != notFound)
+ if (result.m_offset != notFound) {
result.m_structureSet.add(structure);
+ result.m_specificValue = JSValue(specificValue);
+ }
if (result.m_offset != notFound)
ASSERT(result.m_structureSet.size());
@@ -116,29 +167,32 @@
}
case access_get_by_id_self_list: {
- PolymorphicAccessStructureList* list = stubInfo.u.getByIdProtoList.structureList;
- unsigned size = stubInfo.u.getByIdProtoList.listSize;
- for (unsigned i = 0; i < size; ++i) {
+ for (int i = 0; i < listSize; ++i) {
ASSERT(list->list[i].isDirect);
Structure* structure = list->list[i].base.get();
if (result.m_structureSet.contains(structure))
continue;
- size_t myOffset = structure->get(*profiledBlock->globalData(), ident);
+ unsigned attributesIgnored;
+ JSCell* specificValue;
+ size_t myOffset = structure->get(
+ *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
if (myOffset == notFound) {
result.m_offset = notFound;
break;
}
- if (!i)
+ if (!i) {
result.m_offset = myOffset;
- else if (result.m_offset != myOffset) {
+ result.m_specificValue = JSValue(specificValue);
+ } else if (result.m_offset != myOffset) {
result.m_offset = notFound;
break;
- }
-
+ } else if (result.m_specificValue != JSValue(specificValue))
+ result.m_specificValue = JSValue();
+
result.m_structureSet.add(structure);
}
@@ -147,6 +201,27 @@
break;
}
+ case access_get_by_id_proto: {
+ if (!stubInfo.u.getByIdProto.isDirect)
+ return GetByIdStatus(MakesCalls, true);
+ result.m_chain.append(stubInfo.u.getByIdProto.prototypeStructure.get());
+ computeForChain(
+ result, profiledBlock, ident,
+ stubInfo.u.getByIdProto.baseObjectStructure.get());
+ break;
+ }
+
+ case access_get_by_id_chain: {
+ if (!stubInfo.u.getByIdChain.isDirect)
+ return GetByIdStatus(MakesCalls, true);
+ for (unsigned i = 0; i < stubInfo.u.getByIdChain.count; ++i)
+ result.m_chain.append(stubInfo.u.getByIdChain.chain->head()[i].get());
+ computeForChain(
+ result, profiledBlock, ident,
+ stubInfo.u.getByIdChain.baseObjectStructure.get());
+ break;
+ }
+
default:
ASSERT(result.m_offset == notFound);
break;
@@ -155,12 +230,14 @@
if (result.m_offset == notFound) {
result.m_state = TakesSlowPath;
result.m_structureSet.clear();
+ result.m_chain.clear();
+ result.m_specificValue = JSValue();
} else
- result.m_state = SimpleDirect;
+ result.m_state = Simple;
return result;
#else // ENABLE(JIT)
- return GetByIdStatus(NoInformation, StructureSet(), notFound, false);
+ return GetByIdStatus(NoInformation, false);
#endif // ENABLE(JIT)
}
Modified: trunk/Source/_javascript_Core/bytecode/GetByIdStatus.h (119778 => 119779)
--- trunk/Source/_javascript_Core/bytecode/GetByIdStatus.h 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/bytecode/GetByIdStatus.h 2012-06-08 01:31:21 UTC (rev 119779)
@@ -38,7 +38,8 @@
public:
enum State {
NoInformation, // It's uncached so we have no information.
- SimpleDirect, // It's cached for a direct access to a known object property.
+ Simple, // It's cached for a simple access to a known object property with
+ // a possible structure chain and a possible specific value.
TakesSlowPath, // It's known to often take slow path.
MakesCalls // It's known to take paths that make calls.
};
@@ -49,13 +50,17 @@
{
}
- GetByIdStatus(State state, const StructureSet& structureSet, size_t offset, bool wasSeenInJIT)
+ GetByIdStatus(
+ State state, bool wasSeenInJIT, const StructureSet& structureSet = StructureSet(),
+ size_t offset = notFound, JSValue specificValue = JSValue(), Vector<Structure*> chain = Vector<Structure*>())
: m_state(state)
, m_structureSet(structureSet)
+ , m_chain(chain)
+ , m_specificValue(specificValue)
, m_offset(offset)
, m_wasSeenInJIT(wasSeenInJIT)
{
- ASSERT((state == SimpleDirect) == (offset != notFound));
+ ASSERT((state == Simple) == (offset != notFound));
}
static GetByIdStatus computeFor(CodeBlock*, unsigned bytecodeIndex, Identifier&);
@@ -64,20 +69,25 @@
bool isSet() const { return m_state != NoInformation; }
bool operator!() const { return !isSet(); }
- bool isSimpleDirect() const { return m_state == SimpleDirect; }
+ bool isSimple() const { return m_state == Simple; }
bool takesSlowPath() const { return m_state == TakesSlowPath || m_state == MakesCalls; }
bool makesCalls() const { return m_state == MakesCalls; }
const StructureSet& structureSet() const { return m_structureSet; }
+ const Vector<Structure*>& chain() const { return m_chain; } // Returns empty vector if this is a direct access.
+ JSValue specificValue() const { return m_specificValue; } // Returns JSValue() if there is no specific value.
size_t offset() const { return m_offset; }
bool wasSeenInJIT() const { return m_wasSeenInJIT; }
private:
+ static void computeForChain(GetByIdStatus& result, CodeBlock*, Identifier&, Structure*);
static GetByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, Identifier&);
State m_state;
StructureSet m_structureSet;
+ Vector<Structure*> m_chain;
+ JSValue m_specificValue;
size_t m_offset;
bool m_wasSeenInJIT;
};
Modified: trunk/Source/_javascript_Core/bytecode/StructureSet.h (119778 => 119779)
--- trunk/Source/_javascript_Core/bytecode/StructureSet.h 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/bytecode/StructureSet.h 2012-06-08 01:31:21 UTC (rev 119779)
@@ -115,6 +115,14 @@
return true;
}
+ // Call this if you know that the structure set must consist of exactly
+ // one structure.
+ Structure* singletonStructure() const
+ {
+ ASSERT(m_structures.size() == 1);
+ return m_structures[0];
+ }
+
Structure* at(size_t i) const { return m_structures.at(i); }
Structure* operator[](size_t i) const { return at(i); }
Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (119778 => 119779)
--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2012-06-08 01:31:21 UTC (rev 119779)
@@ -102,20 +102,23 @@
u.getByIdSelf.baseObjectStructure.set(globalData, owner, baseObjectStructure);
}
- void initGetByIdProto(JSGlobalData& globalData, JSCell* owner, Structure* baseObjectStructure, Structure* prototypeStructure)
+ void initGetByIdProto(JSGlobalData& globalData, JSCell* owner, Structure* baseObjectStructure, Structure* prototypeStructure, bool isDirect)
{
accessType = access_get_by_id_proto;
u.getByIdProto.baseObjectStructure.set(globalData, owner, baseObjectStructure);
u.getByIdProto.prototypeStructure.set(globalData, owner, prototypeStructure);
+ u.getByIdProto.isDirect = isDirect;
}
- void initGetByIdChain(JSGlobalData& globalData, JSCell* owner, Structure* baseObjectStructure, StructureChain* chain)
+ void initGetByIdChain(JSGlobalData& globalData, JSCell* owner, Structure* baseObjectStructure, StructureChain* chain, unsigned count, bool isDirect)
{
accessType = access_get_by_id_chain;
u.getByIdChain.baseObjectStructure.set(globalData, owner, baseObjectStructure);
u.getByIdChain.chain.set(globalData, owner, chain);
+ u.getByIdChain.count = count;
+ u.getByIdChain.isDirect = isDirect;
}
void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
@@ -251,10 +254,13 @@
struct {
WriteBarrierBase<Structure> baseObjectStructure;
WriteBarrierBase<Structure> prototypeStructure;
+ bool isDirect;
} getByIdProto;
struct {
WriteBarrierBase<Structure> baseObjectStructure;
WriteBarrierBase<StructureChain> chain;
+ unsigned count : 31;
+ bool isDirect : 1;
} getByIdChain;
struct {
PolymorphicAccessStructureList* structureList;
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (119778 => 119779)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2012-06-08 01:31:21 UTC (rev 119779)
@@ -1547,41 +1547,64 @@
int destinationOperand, SpeculatedType prediction, NodeIndex base, unsigned identifierNumber,
const GetByIdStatus& getByIdStatus)
{
- if (getByIdStatus.isSimpleDirect()
- && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
- ASSERT(getByIdStatus.structureSet().size());
+ if (!getByIdStatus.isSimple()
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
+ set(destinationOperand,
+ addToGraph(
+ getByIdStatus.makesCalls() ? GetByIdFlush : GetById,
+ OpInfo(identifierNumber), OpInfo(prediction), base));
+ return;
+ }
+
+ ASSERT(getByIdStatus.structureSet().size());
- // The implementation of GetByOffset does not know to terminate speculative
- // execution if it doesn't have a prediction, so we do it manually.
- if (prediction == SpecNone)
- addToGraph(ForceOSRExit);
+ // The implementation of GetByOffset does not know to terminate speculative
+ // execution if it doesn't have a prediction, so we do it manually.
+ if (prediction == SpecNone)
+ addToGraph(ForceOSRExit);
- addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(getByIdStatus.structureSet())), base);
- NodeIndex propertyStorage;
- size_t offsetOffset;
- if (getByIdStatus.structureSet().allAreUsingInlinePropertyStorage()) {
- propertyStorage = base;
- ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
- offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
- } else {
- propertyStorage = addToGraph(GetPropertyStorage, base);
- offsetOffset = 0;
+ addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(getByIdStatus.structureSet())), base);
+
+ bool useInlineStorage;
+ if (!getByIdStatus.chain().isEmpty()) {
+ Structure* currentStructure = getByIdStatus.structureSet().singletonStructure();
+ JSObject* currentObject = 0;
+ for (unsigned i = 0; i < getByIdStatus.chain().size(); ++i) {
+ currentObject = asObject(currentStructure->prototypeForLookup(m_inlineStackTop->m_codeBlock));
+ currentStructure = getByIdStatus.chain()[i];
+ base = addToGraph(WeakJSConstant, OpInfo(currentObject));
+ addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(currentStructure)), base);
}
+ useInlineStorage = currentStructure->isUsingInlineStorage();
+ } else
+ useInlineStorage = getByIdStatus.structureSet().allAreUsingInlinePropertyStorage();
+
+ if (getByIdStatus.specificValue()) {
+ ASSERT(getByIdStatus.specificValue().isCell());
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);
+ addToGraph(WeakJSConstant, OpInfo(getByIdStatus.specificValue().asCell())));
+ return;
+ }
+
+ NodeIndex propertyStorage;
+ size_t offsetOffset;
+ if (useInlineStorage) {
+ propertyStorage = base;
+ ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
+ offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
} else {
- set(destinationOperand,
- addToGraph(
- getByIdStatus.makesCalls() ? GetByIdFlush : GetById,
- OpInfo(identifierNumber), OpInfo(prediction), base));
+ 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);
}
void ByteCodeParser::prepareToParseBlock()
Modified: trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp (119778 => 119779)
--- trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp 2012-06-08 01:31:21 UTC (rev 119779)
@@ -261,7 +261,7 @@
repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.dfg.deltaCallToStructCheck), CodeLocationLabel(stubInfo.stubRoutine.code()));
repatchBuffer.relink(stubInfo.callReturnLocation, operationGetByIdProtoBuildList);
- stubInfo.initGetByIdChain(*globalData, codeBlock->ownerExecutable(), structure, prototypeChain);
+ stubInfo.initGetByIdChain(*globalData, codeBlock->ownerExecutable(), structure, prototypeChain, count, true);
return true;
}
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (119778 => 119779)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-06-08 01:31:21 UTC (rev 119779)
@@ -945,7 +945,7 @@
offset = slotBaseObject->structure()->get(callFrame->globalData(), propertyName);
}
- stubInfo->initGetByIdProto(callFrame->globalData(), codeBlock->ownerExecutable(), structure, slotBaseObject->structure());
+ stubInfo->initGetByIdProto(callFrame->globalData(), codeBlock->ownerExecutable(), structure, slotBaseObject->structure(), slot.cachedPropertyType() == PropertySlot::Value);
ASSERT(!structure->isDictionary());
ASSERT(!slotBaseObject->structure()->isDictionary());
@@ -961,7 +961,7 @@
}
StructureChain* prototypeChain = structure->prototypeChain(callFrame);
- stubInfo->initGetByIdChain(callFrame->globalData(), codeBlock->ownerExecutable(), structure, prototypeChain);
+ stubInfo->initGetByIdChain(callFrame->globalData(), codeBlock->ownerExecutable(), structure, prototypeChain, count, slot.cachedPropertyType() == PropertySlot::Value);
JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress);
}
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (119778 => 119779)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2012-06-08 01:31:21 UTC (rev 119779)
@@ -381,15 +381,20 @@
return !entry.isNull();
}
- inline JSValue Structure::prototypeForLookup(ExecState* exec) const
+ inline JSValue Structure::prototypeForLookup(JSGlobalObject* globalObject) const
{
if (isObject())
return m_prototype.get();
ASSERT(typeInfo().type() == StringType);
- return exec->lexicalGlobalObject()->stringPrototype();
+ return globalObject->stringPrototype();
}
+ inline JSValue Structure::prototypeForLookup(ExecState* exec) const
+ {
+ return prototypeForLookup(exec->lexicalGlobalObject());
+ }
+
inline StructureChain* Structure::prototypeChain(ExecState* exec) const
{
// We cache our prototype chain so our clients can share it.
Modified: trunk/Source/_javascript_Core/runtime/Structure.h (119778 => 119779)
--- trunk/Source/_javascript_Core/runtime/Structure.h 2012-06-08 01:21:47 UTC (rev 119778)
+++ trunk/Source/_javascript_Core/runtime/Structure.h 2012-06-08 01:31:21 UTC (rev 119779)
@@ -127,6 +127,8 @@
JSValue storedPrototype() const { return m_prototype.get(); }
JSValue prototypeForLookup(ExecState*) const;
+ JSValue prototypeForLookup(JSGlobalObject*) const;
+ JSValue prototypeForLookup(CodeBlock*) const;
StructureChain* prototypeChain(ExecState*) const;
static void visitChildren(JSCell*, SlotVisitor&);