Static table property lookup should not require getOwnPropertySlot override.
authorbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 May 2016 07:09:35 +0000 (07:09 +0000)
committerbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 May 2016 07:09:35 +0000 (07:09 +0000)
commit9925baca3a60c1723d841b56c86e26666a56a846
treec928bc52a6e33ad68c07f061abb7bde29b9ee5f3
parente99b6689609b40667476b04cc1dc26f770707a2e
Static table property lookup should not require getOwnPropertySlot override.
https://bugs.webkit.org/show_bug.cgi?id=158059

Reviewed by Darin Adler.

Currently JSObject does not handle property lookup of entries in the static
table. Each subclass with static properties mut override getOwnPropertySlot,
and explicitly call the lookup functions. This has the following drawbacks:

- Performance: for any class with static properties, property acces becomes
  virtual (via method table).
- Poor encapsulation: implementation detail of static property access is
  spread throughout & cross projects, rather than being contained in JSObject.
- Code size: this results in a great many additional functions.
- Inconsistency: static table presence has to be be taken into account in many
  other operations, e.g. presence of read-only properties for put.
- Memory: in order to avoid the virtual lookup, DOM prototypes eagerly reify
  all properties. This is likely suboptimal.

Instead, JSObject::getPropertySlot / JSObject::getOwnPropertySlot should be
able to handle static properties.

This is actually a fairly small & simple change.

The common pattern is for subclasses of JObject to override getOwnPropertySlot
to first defer to JSObject for property storage lookup, and only if this fails
consult the static table. They just want the static tables to be consulted after
regular property storgae lookup. So just add a fast flag in TypeInfo for JSObject
to check, and where it is set, do so. Then it's just a question of switching
classes over to start setting this flag, and drop the override.

The new mechanism does change static table lookup order from oldest-ancestor
first to most-derived first. The new ordering makes more sense (means derived
class static tables can now override entries from parents), and shoudn't affect
any existing code (since overriding didn't previously work, there likely aren't
shadowing properties in more derived types).

This patch changes all classes in JavaScriptCore over to using the new mechanism,
except JSGlobalObject. I'll move classes in WebCore over as a separate patch
(this is also why I've not moved JSGlobalObject in this patch - doing so would
move JSDOMWindow, and I'd rather handle that separately).

* runtime/JSTypeInfo.h:
(JSC::TypeInfo::hasStaticPropertyTable):
    - Add HasStaticPropertyTable flag.
* runtime/Lookup.cpp:
(JSC::setUpStaticFunctionSlot):
    - Change setUpStaticFunctionSlot to take a VM&.
* runtime/Lookup.h:
(JSC::getStaticPropertySlotFromTable):
    - Added helper function to perform static lookup alone.
(JSC::getStaticPropertySlot):
(JSC::getStaticFunctionSlot):
    - setUpStaticFunctionSlot changed to take a VM&.
* runtime/JSObject.cpp:
(JSC::JSObject::getOwnStaticPropertySlot):
    - Added, walks ClassInfo chain looking for static properties.
* runtime/JSObject.h:
(JSC::JSObject::getOwnNonIndexPropertySlot):
    - getOwnNonIndexPropertySlot is used internally by getPropertySlot
      & getOwnPropertySlot. If property is not present in storage array
      then check the static table.
* runtime/ArrayConstructor.cpp:
(JSC::ArrayConstructor::finishCreation):
(JSC::constructArrayWithSizeQuirk):
(JSC::ArrayConstructor::getOwnPropertySlot): Deleted.
* runtime/ArrayConstructor.h:
(JSC::ArrayConstructor::create):
* runtime/ArrayIteratorPrototype.cpp:
(JSC::ArrayIteratorPrototype::finishCreation):
(JSC::ArrayIteratorPrototype::getOwnPropertySlot): Deleted.
* runtime/ArrayIteratorPrototype.h:
(JSC::ArrayIteratorPrototype::create):
(JSC::ArrayIteratorPrototype::ArrayIteratorPrototype):
* runtime/BooleanPrototype.cpp:
(JSC::BooleanPrototype::finishCreation):
(JSC::booleanProtoFuncToString):
(JSC::BooleanPrototype::getOwnPropertySlot): Deleted.
* runtime/BooleanPrototype.h:
(JSC::BooleanPrototype::create):
* runtime/DateConstructor.cpp:
(JSC::DateConstructor::finishCreation):
(JSC::millisecondsFromComponents):
(JSC::DateConstructor::getOwnPropertySlot): Deleted.
* runtime/DateConstructor.h:
(JSC::DateConstructor::create):
* runtime/DatePrototype.cpp:
(JSC::DatePrototype::finishCreation):
(JSC::dateProtoFuncToString):
(JSC::DatePrototype::getOwnPropertySlot): Deleted.
* runtime/DatePrototype.h:
(JSC::DatePrototype::create):
* runtime/ErrorPrototype.cpp:
(JSC::ErrorPrototype::finishCreation):
(JSC::ErrorPrototype::getOwnPropertySlot): Deleted.
* runtime/ErrorPrototype.h:
(JSC::ErrorPrototype::create):
* runtime/GeneratorPrototype.cpp:
(JSC::GeneratorPrototype::finishCreation):
(JSC::GeneratorPrototype::getOwnPropertySlot): Deleted.
* runtime/GeneratorPrototype.h:
(JSC::GeneratorPrototype::create):
(JSC::GeneratorPrototype::createStructure):
(JSC::GeneratorPrototype::GeneratorPrototype):
* runtime/InspectorInstrumentationObject.cpp:
(JSC::InspectorInstrumentationObject::finishCreation):
(JSC::InspectorInstrumentationObject::isEnabled):
(JSC::InspectorInstrumentationObject::getOwnPropertySlot): Deleted.
* runtime/InspectorInstrumentationObject.h:
(JSC::InspectorInstrumentationObject::create):
(JSC::InspectorInstrumentationObject::createStructure):
* runtime/IntlCollatorConstructor.cpp:
(JSC::IntlCollatorConstructor::getCallData):
(JSC::IntlCollatorConstructorFuncSupportedLocalesOf):
(JSC::IntlCollatorConstructor::getOwnPropertySlot): Deleted.
* runtime/IntlCollatorConstructor.h:
* runtime/IntlCollatorPrototype.cpp:
(JSC::IntlCollatorPrototype::finishCreation):
(JSC::IntlCollatorFuncCompare):
(JSC::IntlCollatorPrototype::getOwnPropertySlot): Deleted.
* runtime/IntlCollatorPrototype.h:
* runtime/IntlDateTimeFormatConstructor.cpp:
(JSC::IntlDateTimeFormatConstructor::getCallData):
(JSC::IntlDateTimeFormatConstructorFuncSupportedLocalesOf):
(JSC::IntlDateTimeFormatConstructor::getOwnPropertySlot): Deleted.
* runtime/IntlDateTimeFormatConstructor.h:
* runtime/IntlDateTimeFormatPrototype.cpp:
(JSC::IntlDateTimeFormatPrototype::finishCreation):
(JSC::IntlDateTimeFormatFuncFormatDateTime):
(JSC::IntlDateTimeFormatPrototype::getOwnPropertySlot): Deleted.
* runtime/IntlDateTimeFormatPrototype.h:
* runtime/IntlNumberFormatConstructor.cpp:
(JSC::IntlNumberFormatConstructor::getCallData):
(JSC::IntlNumberFormatConstructorFuncSupportedLocalesOf):
(JSC::IntlNumberFormatConstructor::getOwnPropertySlot): Deleted.
* runtime/IntlNumberFormatConstructor.h:
* runtime/IntlNumberFormatPrototype.cpp:
(JSC::IntlNumberFormatPrototype::finishCreation):
(JSC::IntlNumberFormatFuncFormatNumber):
(JSC::IntlNumberFormatPrototype::getOwnPropertySlot): Deleted.
* runtime/IntlNumberFormatPrototype.h:
* runtime/JSDataViewPrototype.cpp:
(JSC::JSDataViewPrototype::createStructure):
(JSC::getData):
(JSC::JSDataViewPrototype::getOwnPropertySlot): Deleted.
* runtime/JSDataViewPrototype.h:
* runtime/JSInternalPromiseConstructor.cpp:
(JSC::JSInternalPromiseConstructor::getCallData):
(JSC::JSInternalPromiseConstructor::getOwnPropertySlot): Deleted.
* runtime/JSInternalPromiseConstructor.h:
* runtime/JSONObject.cpp:
(JSC::Walker::Walker):
(JSC::JSONObject::getOwnPropertySlot): Deleted.
* runtime/JSONObject.h:
(JSC::JSONObject::create):
* runtime/JSPromiseConstructor.cpp:
(JSC::JSPromiseConstructor::getCallData):
(JSC::JSPromiseConstructor::getOwnPropertySlot): Deleted.
* runtime/JSPromiseConstructor.h:
* runtime/JSPromisePrototype.cpp:
(JSC::JSPromisePrototype::addOwnInternalSlots):
(JSC::JSPromisePrototype::getOwnPropertySlot): Deleted.
* runtime/JSPromisePrototype.h:
* runtime/MapPrototype.cpp:
(JSC::MapPrototype::finishCreation):
(JSC::getMap):
(JSC::MapPrototype::getOwnPropertySlot): Deleted.
* runtime/MapPrototype.h:
(JSC::MapPrototype::create):
(JSC::MapPrototype::MapPrototype):
* runtime/ModuleLoaderObject.cpp:
(JSC::ModuleLoaderObject::finishCreation):
(JSC::printableModuleKey):
(JSC::ModuleLoaderObject::getOwnPropertySlot): Deleted.
* runtime/ModuleLoaderObject.h:
* runtime/NumberPrototype.cpp:
(JSC::NumberPrototype::finishCreation):
(JSC::toThisNumber):
(JSC::NumberPrototype::getOwnPropertySlot): Deleted.
* runtime/NumberPrototype.h:
(JSC::NumberPrototype::create):
* runtime/ObjectConstructor.cpp:
(JSC::ObjectConstructor::addDefineProperty):
(JSC::constructObject):
(JSC::ObjectConstructor::getOwnPropertySlot): Deleted.
* runtime/ObjectConstructor.h:
(JSC::ObjectConstructor::create):
(JSC::ObjectConstructor::createStructure):
* runtime/ReflectObject.cpp:
(JSC::ReflectObject::finishCreation):
(JSC::ReflectObject::getOwnPropertySlot): Deleted.
* runtime/ReflectObject.h:
(JSC::ReflectObject::create):
(JSC::ReflectObject::createStructure):
* runtime/RegExpConstructor.cpp:
(JSC::RegExpConstructor::getRightContext):
(JSC::regExpConstructorDollar):
(JSC::RegExpConstructor::getOwnPropertySlot): Deleted.
* runtime/RegExpConstructor.h:
(JSC::RegExpConstructor::create):
(JSC::RegExpConstructor::createStructure):
* runtime/SetPrototype.cpp:
(JSC::SetPrototype::finishCreation):
(JSC::getSet):
(JSC::SetPrototype::getOwnPropertySlot): Deleted.
* runtime/SetPrototype.h:
(JSC::SetPrototype::create):
(JSC::SetPrototype::SetPrototype):
* runtime/StringConstructor.cpp:
(JSC::StringConstructor::finishCreation):
(JSC::stringFromCharCodeSlowCase):
(JSC::StringConstructor::getOwnPropertySlot): Deleted.
* runtime/StringConstructor.h:
(JSC::StringConstructor::create):
* runtime/StringIteratorPrototype.cpp:
(JSC::StringIteratorPrototype::finishCreation):
(JSC::StringIteratorPrototype::getOwnPropertySlot): Deleted.
* runtime/StringIteratorPrototype.h:
(JSC::StringIteratorPrototype::create):
(JSC::StringIteratorPrototype::StringIteratorPrototype):
* runtime/StringPrototype.cpp:
(JSC::StringPrototype::create):
(JSC::substituteBackreferencesSlow):
(JSC::StringPrototype::getOwnPropertySlot): Deleted.
* runtime/StringPrototype.h:
* runtime/SymbolConstructor.cpp:
(JSC::SymbolConstructor::finishCreation):
(JSC::callSymbol):
(JSC::SymbolConstructor::getOwnPropertySlot): Deleted.
* runtime/SymbolConstructor.h:
(JSC::SymbolConstructor::create):
* runtime/SymbolPrototype.cpp:
(JSC::SymbolPrototype::finishCreation):
(JSC::SymbolPrototype::getOwnPropertySlot): Deleted.
* runtime/SymbolPrototype.h:
(JSC::SymbolPrototype::create):
    - remove getOwnPropertySlot, replace OverridesGetOwnPropertySlot flag with HasStaticPropertyTable.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@201448 268f45cc-cd09-0410-ab3c-d52691b4dbfc
68 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/ArrayConstructor.cpp
Source/JavaScriptCore/runtime/ArrayConstructor.h
Source/JavaScriptCore/runtime/ArrayIteratorPrototype.cpp
Source/JavaScriptCore/runtime/ArrayIteratorPrototype.h
Source/JavaScriptCore/runtime/BooleanPrototype.cpp
Source/JavaScriptCore/runtime/BooleanPrototype.h
Source/JavaScriptCore/runtime/DateConstructor.cpp
Source/JavaScriptCore/runtime/DateConstructor.h
Source/JavaScriptCore/runtime/DatePrototype.cpp
Source/JavaScriptCore/runtime/DatePrototype.h
Source/JavaScriptCore/runtime/ErrorPrototype.cpp
Source/JavaScriptCore/runtime/ErrorPrototype.h
Source/JavaScriptCore/runtime/GeneratorPrototype.cpp
Source/JavaScriptCore/runtime/GeneratorPrototype.h
Source/JavaScriptCore/runtime/InspectorInstrumentationObject.cpp
Source/JavaScriptCore/runtime/InspectorInstrumentationObject.h
Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp
Source/JavaScriptCore/runtime/IntlCollatorConstructor.h
Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp
Source/JavaScriptCore/runtime/IntlCollatorPrototype.h
Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp
Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.h
Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp
Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.h
Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp
Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.h
Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp
Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.h
Source/JavaScriptCore/runtime/JSDataViewPrototype.cpp
Source/JavaScriptCore/runtime/JSDataViewPrototype.h
Source/JavaScriptCore/runtime/JSInternalPromiseConstructor.cpp
Source/JavaScriptCore/runtime/JSInternalPromiseConstructor.h
Source/JavaScriptCore/runtime/JSONObject.cpp
Source/JavaScriptCore/runtime/JSONObject.h
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp
Source/JavaScriptCore/runtime/JSPromiseConstructor.h
Source/JavaScriptCore/runtime/JSPromisePrototype.cpp
Source/JavaScriptCore/runtime/JSPromisePrototype.h
Source/JavaScriptCore/runtime/JSTypeInfo.h
Source/JavaScriptCore/runtime/Lookup.cpp
Source/JavaScriptCore/runtime/Lookup.h
Source/JavaScriptCore/runtime/MapPrototype.cpp
Source/JavaScriptCore/runtime/MapPrototype.h
Source/JavaScriptCore/runtime/ModuleLoaderObject.cpp
Source/JavaScriptCore/runtime/ModuleLoaderObject.h
Source/JavaScriptCore/runtime/NumberPrototype.cpp
Source/JavaScriptCore/runtime/NumberPrototype.h
Source/JavaScriptCore/runtime/ObjectConstructor.cpp
Source/JavaScriptCore/runtime/ObjectConstructor.h
Source/JavaScriptCore/runtime/ReflectObject.cpp
Source/JavaScriptCore/runtime/ReflectObject.h
Source/JavaScriptCore/runtime/RegExpConstructor.cpp
Source/JavaScriptCore/runtime/RegExpConstructor.h
Source/JavaScriptCore/runtime/SetPrototype.cpp
Source/JavaScriptCore/runtime/SetPrototype.h
Source/JavaScriptCore/runtime/StringConstructor.cpp
Source/JavaScriptCore/runtime/StringConstructor.h
Source/JavaScriptCore/runtime/StringIteratorPrototype.cpp
Source/JavaScriptCore/runtime/StringIteratorPrototype.h
Source/JavaScriptCore/runtime/StringPrototype.cpp
Source/JavaScriptCore/runtime/StringPrototype.h
Source/JavaScriptCore/runtime/SymbolConstructor.cpp
Source/JavaScriptCore/runtime/SymbolConstructor.h
Source/JavaScriptCore/runtime/SymbolPrototype.cpp
Source/JavaScriptCore/runtime/SymbolPrototype.h