summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-06-20 13:01:08 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-06-20 13:01:08 +0200
commit49233e234e5c787396cadb2cea33b31ae0cd65c1 (patch)
tree5410cb9a8fd53168bb60d62c54b654d86f03c38d /Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
parentb211c645d8ab690f713515dfdc84d80b11c27d2c (diff)
downloadqtwebkit-49233e234e5c787396cadb2cea33b31ae0cd65c1.tar.gz
Imported WebKit commit 3a8c29f35d00659d2ce7a0ccdfa8304f14e82327 (http://svn.webkit.org/repository/webkit/trunk@120813)
New snapshot with Windows build fixes
Diffstat (limited to 'Source/JavaScriptCore/bytecode/GetByIdStatus.cpp')
-rw-r--r--Source/JavaScriptCore/bytecode/GetByIdStatus.cpp115
1 files changed, 96 insertions, 19 deletions
diff --git a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
index 11aead3df..a62a43f7f 100644
--- a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
@@ -44,15 +44,61 @@ GetByIdStatus GetByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned
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);
+ UNREACHABLE_FOR_PLATFORM();
#endif
}
@@ -89,12 +135,12 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
}
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 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
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 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
}
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 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
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 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
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)
}