summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2016-08-25 19:20:41 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-02-02 12:30:55 +0000
commit6882a04fb36642862b11efe514251d32070c3d65 (patch)
treeb7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
parentab6df191029eeeb0b0f16f127d553265659f739e (diff)
downloadqtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/bytecode/StructureStubInfo.cpp')
-rw-r--r--Source/JavaScriptCore/bytecode/StructureStubInfo.cpp208
1 files changed, 141 insertions, 67 deletions
diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
index 70cf2fccb..5ffd743a6 100644
--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2014, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,97 +26,171 @@
#include "config.h"
#include "StructureStubInfo.h"
+#include "JSCellInlines.h"
#include "JSObject.h"
-#include "PolymorphicPutByIdList.h"
-
+#include "PolymorphicAccess.h"
+#include "Repatch.h"
namespace JSC {
#if ENABLE(JIT)
+StructureStubInfo::StructureStubInfo(AccessType accessType)
+ : callSiteIndex(UINT_MAX)
+ , accessType(accessType)
+ , cacheType(CacheType::Unset)
+ , countdown(1) // For a totally clear stub, we'll patch it after the first execution.
+ , repatchCount(0)
+ , numberOfCoolDowns(0)
+ , resetByGC(false)
+ , tookSlowPath(false)
+ , everConsidered(false)
+{
+}
+
+StructureStubInfo::~StructureStubInfo()
+{
+}
+
+void StructureStubInfo::initGetByIdSelf(CodeBlock* codeBlock, Structure* baseObjectStructure, PropertyOffset offset)
+{
+ cacheType = CacheType::GetByIdSelf;
+
+ u.byIdSelf.baseObjectStructure.set(
+ *codeBlock->vm(), codeBlock, baseObjectStructure);
+ u.byIdSelf.offset = offset;
+}
+
+void StructureStubInfo::initPutByIdReplace(CodeBlock* codeBlock, Structure* baseObjectStructure, PropertyOffset offset)
+{
+ cacheType = CacheType::PutByIdReplace;
+
+ u.byIdSelf.baseObjectStructure.set(
+ *codeBlock->vm(), codeBlock, baseObjectStructure);
+ u.byIdSelf.offset = offset;
+}
+
+void StructureStubInfo::initStub(CodeBlock*, std::unique_ptr<PolymorphicAccess> stub)
+{
+ cacheType = CacheType::Stub;
+ u.stub = stub.release();
+}
+
void StructureStubInfo::deref()
{
- switch (accessType) {
- case access_get_by_id_self_list: {
- PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
- delete polymorphicStructures;
+ switch (cacheType) {
+ case CacheType::Stub:
+ delete u.stub;
return;
- }
- case access_get_by_id_proto_list: {
- PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList;
- delete polymorphicStructures;
+ case CacheType::Unset:
+ case CacheType::GetByIdSelf:
+ case CacheType::PutByIdReplace:
return;
}
- case access_put_by_id_list:
- delete u.putByIdList.list;
+
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+void StructureStubInfo::aboutToDie()
+{
+ switch (cacheType) {
+ case CacheType::Stub:
+ u.stub->aboutToDie();
return;
- case access_get_by_id_self:
- case access_get_by_id_proto:
- case access_get_by_id_chain:
- case access_put_by_id_transition_normal:
- case access_put_by_id_transition_direct:
- case access_put_by_id_replace:
- case access_unset:
- case access_get_by_id_generic:
- case access_put_by_id_generic:
- case access_get_array_length:
- case access_get_string_length:
- // These instructions don't have to release any allocated memory
+ case CacheType::Unset:
+ case CacheType::GetByIdSelf:
+ case CacheType::PutByIdReplace:
return;
- default:
- RELEASE_ASSERT_NOT_REACHED();
}
+
+ RELEASE_ASSERT_NOT_REACHED();
}
-bool StructureStubInfo::visitWeakReferences()
+MacroAssemblerCodePtr StructureStubInfo::addAccessCase(
+ CodeBlock* codeBlock, const Identifier& ident, std::unique_ptr<AccessCase> accessCase)
{
+ VM& vm = *codeBlock->vm();
+
+ if (!accessCase)
+ return MacroAssemblerCodePtr();
+
+ if (cacheType == CacheType::Stub)
+ return u.stub->regenerateWithCase(vm, codeBlock, *this, ident, WTFMove(accessCase));
+
+ std::unique_ptr<PolymorphicAccess> access = std::make_unique<PolymorphicAccess>();
+
+ Vector<std::unique_ptr<AccessCase>> accessCases;
+
+ std::unique_ptr<AccessCase> previousCase =
+ AccessCase::fromStructureStubInfo(vm, codeBlock, *this);
+ if (previousCase)
+ accessCases.append(WTFMove(previousCase));
+
+ accessCases.append(WTFMove(accessCase));
+
+ MacroAssemblerCodePtr result =
+ access->regenerateWithCases(vm, codeBlock, *this, ident, WTFMove(accessCases));
+
+ if (!result)
+ return MacroAssemblerCodePtr();
+
+ initStub(codeBlock, WTFMove(access));
+ return result;
+}
+
+void StructureStubInfo::reset(CodeBlock* codeBlock)
+{
+ if (cacheType == CacheType::Unset)
+ return;
+
+ if (Options::verboseOSR()) {
+ // This can be called from GC destructor calls, so we don't try to do a full dump
+ // of the CodeBlock.
+ dataLog("Clearing structure cache (kind ", static_cast<int>(accessType), ") in ", RawPointer(codeBlock), ".\n");
+ }
+
switch (accessType) {
- case access_get_by_id_self:
- if (!Heap::isMarked(u.getByIdSelf.baseObjectStructure.get()))
- return false;
- break;
- case access_get_by_id_proto:
- if (!Heap::isMarked(u.getByIdProto.baseObjectStructure.get())
- || !Heap::isMarked(u.getByIdProto.prototypeStructure.get()))
- return false;
- break;
- case access_get_by_id_chain:
- if (!Heap::isMarked(u.getByIdChain.baseObjectStructure.get())
- || !Heap::isMarked(u.getByIdChain.chain.get()))
- return false;
+ case AccessType::Get:
+ resetGetByID(codeBlock, *this);
break;
- case access_get_by_id_self_list: {
- PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
- if (!polymorphicStructures->visitWeak(u.getByIdSelfList.listSize))
- return false;
+ case AccessType::Put:
+ resetPutByID(codeBlock, *this);
break;
- }
- case access_get_by_id_proto_list: {
- PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList;
- if (!polymorphicStructures->visitWeak(u.getByIdProtoList.listSize))
- return false;
+ case AccessType::In:
+ resetIn(codeBlock, *this);
break;
}
- case access_put_by_id_transition_normal:
- case access_put_by_id_transition_direct:
- if (!Heap::isMarked(u.putByIdTransition.previousStructure.get())
- || !Heap::isMarked(u.putByIdTransition.structure.get())
- || !Heap::isMarked(u.putByIdTransition.chain.get()))
- return false;
- break;
- case access_put_by_id_replace:
- if (!Heap::isMarked(u.putByIdReplace.baseObjectStructure.get()))
- return false;
+
+ deref();
+ cacheType = CacheType::Unset;
+}
+
+void StructureStubInfo::visitWeakReferences(CodeBlock* codeBlock)
+{
+ VM& vm = *codeBlock->vm();
+
+ switch (cacheType) {
+ case CacheType::GetByIdSelf:
+ case CacheType::PutByIdReplace:
+ if (Heap::isMarked(u.byIdSelf.baseObjectStructure.get()))
+ return;
break;
- case access_put_by_id_list:
- if (!u.putByIdList.list->visitWeak())
- return false;
+ case CacheType::Stub:
+ if (u.stub->visitWeak(vm))
+ return;
break;
default:
- // The rest of the instructions don't require references, so there is no need to
- // do anything.
- break;
+ return;
}
- return true;
+
+ reset(codeBlock);
+ resetByGC = true;
+}
+
+bool StructureStubInfo::containsPC(void* pc) const
+{
+ if (cacheType != CacheType::Stub)
+ return false;
+ return u.stub->containsPC(pc);
}
#endif