diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/runtime/SymbolTable.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/runtime/SymbolTable.cpp')
-rw-r--r-- | Source/JavaScriptCore/runtime/SymbolTable.cpp | 229 |
1 files changed, 174 insertions, 55 deletions
diff --git a/Source/JavaScriptCore/runtime/SymbolTable.cpp b/Source/JavaScriptCore/runtime/SymbolTable.cpp index 556dbf7af..55c6dd2ba 100644 --- a/Source/JavaScriptCore/runtime/SymbolTable.cpp +++ b/Source/JavaScriptCore/runtime/SymbolTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2012, 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 @@ -10,7 +10,7 @@ * 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -30,12 +30,13 @@ #include "SymbolTable.h" #include "JSDestructibleObject.h" -#include "Operations.h" +#include "JSCInlines.h" #include "SlotVisitorInlines.h" +#include "TypeProfiler.h" namespace JSC { -const ClassInfo SymbolTable::s_info = { "SymbolTable", 0, 0, 0, CREATE_METHOD_TABLE(SymbolTable) }; +const ClassInfo SymbolTable::s_info = { "SymbolTable", 0, 0, CREATE_METHOD_TABLE(SymbolTable) }; SymbolTableEntry& SymbolTableEntry::copySlow(const SymbolTableEntry& other) { @@ -48,7 +49,7 @@ SymbolTableEntry& SymbolTableEntry::copySlow(const SymbolTableEntry& other) void SymbolTable::destroy(JSCell* cell) { - SymbolTable* thisObject = jsCast<SymbolTable*>(cell); + SymbolTable* thisObject = static_cast<SymbolTable*>(cell); thisObject->SymbolTable::~SymbolTable(); } @@ -58,19 +59,14 @@ void SymbolTableEntry::freeFatEntrySlow() delete fatEntry(); } -JSValue SymbolTableEntry::inferredValue() -{ - if (!isFat()) - return JSValue(); - return fatEntry()->m_watchpoints->inferredValue(); -} - void SymbolTableEntry::prepareToWatch() { + if (!isWatchable()) + return; FatEntry* entry = inflate(); if (entry->m_watchpoints) return; - entry->m_watchpoints = adoptRef(new VariableWatchpointSet()); + entry->m_watchpoints = adoptRef(new WatchpointSet(ClearWatchpoint)); } void SymbolTableEntry::addWatchpoint(Watchpoint* watchpoint) @@ -78,15 +74,6 @@ void SymbolTableEntry::addWatchpoint(Watchpoint* watchpoint) fatEntry()->m_watchpoints->add(watchpoint); } -void SymbolTableEntry::notifyWriteSlow(JSValue value) -{ - VariableWatchpointSet* watchpoints = fatEntry()->m_watchpoints.get(); - if (!watchpoints) - return; - - watchpoints->notifyWrite(value); -} - SymbolTableEntry::FatEntry* SymbolTableEntry::inflateSlow() { FatEntry* entry = new FatEntry(m_bits); @@ -96,69 +83,201 @@ SymbolTableEntry::FatEntry* SymbolTableEntry::inflateSlow() SymbolTable::SymbolTable(VM& vm) : JSCell(vm, vm.symbolTableStructure.get()) - , m_parameterCountIncludingThis(0) , m_usesNonStrictEval(false) - , m_captureStart(0) - , m_captureEnd(0) - , m_functionEnteredOnce(ClearWatchpoint) + , m_nestedLexicalScope(false) + , m_scopeType(VarScope) { } SymbolTable::~SymbolTable() { } +void SymbolTable::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + m_singletonScope.set(vm, this, InferredValue::create(vm)); +} + void SymbolTable::visitChildren(JSCell* thisCell, SlotVisitor& visitor) { SymbolTable* thisSymbolTable = jsCast<SymbolTable*>(thisCell); - if (!thisSymbolTable->m_watchpointCleanup) { - thisSymbolTable->m_watchpointCleanup = - std::make_unique<WatchpointCleanup>(thisSymbolTable); - } - visitor.addUnconditionalFinalizer(thisSymbolTable->m_watchpointCleanup.get()); + visitor.append(thisSymbolTable->m_arguments); + visitor.append(thisSymbolTable->m_singletonScope); + + if (thisSymbolTable->m_rareData) + visitor.append(thisSymbolTable->m_rareData->m_codeBlock); + + // Save some memory. This is O(n) to rebuild and we do so on the fly. + ConcurrentJSLocker locker(thisSymbolTable->m_lock); + thisSymbolTable->m_localToEntry = nullptr; } -SymbolTable::WatchpointCleanup::WatchpointCleanup(SymbolTable* symbolTable) - : m_symbolTable(symbolTable) +const SymbolTable::LocalToEntryVec& SymbolTable::localToEntry(const ConcurrentJSLocker&) { + if (UNLIKELY(!m_localToEntry)) { + unsigned size = 0; + for (auto& entry : m_map) { + VarOffset offset = entry.value.varOffset(); + if (offset.isScope()) + size = std::max(size, offset.scopeOffset().offset() + 1); + } + + m_localToEntry = std::make_unique<LocalToEntryVec>(size, nullptr); + for (auto& entry : m_map) { + VarOffset offset = entry.value.varOffset(); + if (offset.isScope()) + m_localToEntry->at(offset.scopeOffset().offset()) = &entry.value; + } + } + + return *m_localToEntry; } -SymbolTable::WatchpointCleanup::~WatchpointCleanup() { } - -void SymbolTable::WatchpointCleanup::finalizeUnconditionally() +SymbolTableEntry* SymbolTable::entryFor(const ConcurrentJSLocker& locker, ScopeOffset offset) { - Map::iterator iter = m_symbolTable->m_map.begin(); - Map::iterator end = m_symbolTable->m_map.end(); - for (; iter != end; ++iter) { - if (VariableWatchpointSet* set = iter->value.watchpointSet()) - set->finalizeUnconditionally(); - } + auto& toEntryVector = localToEntry(locker); + if (offset.offset() >= toEntryVector.size()) + return nullptr; + return toEntryVector[offset.offset()]; } -SymbolTable* SymbolTable::clone(VM& vm) +SymbolTable* SymbolTable::cloneScopePart(VM& vm) { SymbolTable* result = SymbolTable::create(vm); - result->m_parameterCountIncludingThis = m_parameterCountIncludingThis; result->m_usesNonStrictEval = m_usesNonStrictEval; - result->m_captureStart = m_captureStart; - result->m_captureEnd = m_captureEnd; - - Map::iterator iter = m_map.begin(); - Map::iterator end = m_map.end(); - for (; iter != end; ++iter) { + result->m_nestedLexicalScope = m_nestedLexicalScope; + result->m_scopeType = m_scopeType; + + for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) { + if (!iter->value.varOffset().isScope()) + continue; result->m_map.add( iter->key, - SymbolTableEntry(iter->value.getIndex(), iter->value.getAttributes())); + SymbolTableEntry(iter->value.varOffset(), iter->value.getAttributes())); } - if (m_slowArguments) { - result->m_slowArguments = std::make_unique<SlowArgument[]>(parameterCount()); - for (unsigned i = parameterCount(); i--;) - result->m_slowArguments[i] = m_slowArguments[i]; + result->m_maxScopeOffset = m_maxScopeOffset; + + if (ScopedArgumentsTable* arguments = this->arguments()) + result->m_arguments.set(vm, result, arguments); + + if (m_rareData) { + result->m_rareData = std::make_unique<SymbolTableRareData>(); + + { + auto iter = m_rareData->m_uniqueIDMap.begin(); + auto end = m_rareData->m_uniqueIDMap.end(); + for (; iter != end; ++iter) + result->m_rareData->m_uniqueIDMap.set(iter->key, iter->value); + } + + { + auto iter = m_rareData->m_offsetToVariableMap.begin(); + auto end = m_rareData->m_offsetToVariableMap.end(); + for (; iter != end; ++iter) + result->m_rareData->m_offsetToVariableMap.set(iter->key, iter->value); + } + + { + auto iter = m_rareData->m_uniqueTypeSetMap.begin(); + auto end = m_rareData->m_uniqueTypeSetMap.end(); + for (; iter != end; ++iter) + result->m_rareData->m_uniqueTypeSetMap.set(iter->key, iter->value); + } } return result; } +void SymbolTable::prepareForTypeProfiling(const ConcurrentJSLocker&) +{ + if (m_rareData) + return; + + m_rareData = std::make_unique<SymbolTableRareData>(); + + for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) { + m_rareData->m_uniqueIDMap.set(iter->key, TypeProfilerNeedsUniqueIDGeneration); + m_rareData->m_offsetToVariableMap.set(iter->value.varOffset(), iter->key); + } +} + +CodeBlock* SymbolTable::rareDataCodeBlock() +{ + if (!m_rareData) + return nullptr; + + return m_rareData->m_codeBlock.get(); +} + +void SymbolTable::setRareDataCodeBlock(CodeBlock* codeBlock) +{ + if (!m_rareData) + m_rareData = std::make_unique<SymbolTableRareData>(); + + ASSERT(!m_rareData->m_codeBlock); + m_rareData->m_codeBlock.set(*codeBlock->vm(), this, codeBlock); +} + +GlobalVariableID SymbolTable::uniqueIDForVariable(const ConcurrentJSLocker&, UniquedStringImpl* key, VM& vm) +{ + RELEASE_ASSERT(m_rareData); + + auto iter = m_rareData->m_uniqueIDMap.find(key); + auto end = m_rareData->m_uniqueIDMap.end(); + if (iter == end) + return TypeProfilerNoGlobalIDExists; + + GlobalVariableID id = iter->value; + if (id == TypeProfilerNeedsUniqueIDGeneration) { + id = vm.typeProfiler()->getNextUniqueVariableID(); + m_rareData->m_uniqueIDMap.set(key, id); + m_rareData->m_uniqueTypeSetMap.set(key, TypeSet::create()); // Make a new global typeset for this corresponding ID. + } + + return id; +} + +GlobalVariableID SymbolTable::uniqueIDForOffset(const ConcurrentJSLocker& locker, VarOffset offset, VM& vm) +{ + RELEASE_ASSERT(m_rareData); + + auto iter = m_rareData->m_offsetToVariableMap.find(offset); + auto end = m_rareData->m_offsetToVariableMap.end(); + if (iter == end) + return TypeProfilerNoGlobalIDExists; + + return uniqueIDForVariable(locker, iter->value.get(), vm); +} + +RefPtr<TypeSet> SymbolTable::globalTypeSetForOffset(const ConcurrentJSLocker& locker, VarOffset offset, VM& vm) +{ + RELEASE_ASSERT(m_rareData); + + uniqueIDForOffset(locker, offset, vm); // Lazily create the TypeSet if necessary. + + auto iter = m_rareData->m_offsetToVariableMap.find(offset); + auto end = m_rareData->m_offsetToVariableMap.end(); + if (iter == end) + return nullptr; + + return globalTypeSetForVariable(locker, iter->value.get(), vm); +} + +RefPtr<TypeSet> SymbolTable::globalTypeSetForVariable(const ConcurrentJSLocker& locker, UniquedStringImpl* key, VM& vm) +{ + RELEASE_ASSERT(m_rareData); + + uniqueIDForVariable(locker, key, vm); // Lazily create the TypeSet if necessary. + + auto iter = m_rareData->m_uniqueTypeSetMap.find(key); + auto end = m_rareData->m_uniqueTypeSetMap.end(); + if (iter == end) + return nullptr; + + return iter->value; +} + } // namespace JSC |