[JSC] Add more JSType based fast path for jsDynamicCast
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Mar 2018 17:18:49 +0000 (17:18 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Mar 2018 17:18:49 +0000 (17:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=183403

Reviewed by Mark Lam.

We add more JSType based fast path for jsDynamicCast. Basically, we add miscellaneous JSTypes which
are used for jsDynamicCast in JSC, arguments types, and scope types.

We also add ClassInfo to JSScope and JSSegmentedVariableObject since they are used with jsDynamicCast.

* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setUpCall):
* runtime/ClonedArguments.h:
(JSC::ClonedArguments::specialsMaterialized const): Deleted.
* runtime/DirectArguments.h:
(JSC::DirectArguments::subspaceFor): Deleted.
(JSC::DirectArguments::internalLength const): Deleted.
(JSC::DirectArguments::length const): Deleted.
(JSC::DirectArguments::isMappedArgument const): Deleted.
(JSC::DirectArguments::isMappedArgumentInDFG const): Deleted.
(JSC::DirectArguments::getIndexQuickly const): Deleted.
(JSC::DirectArguments::setIndexQuickly): Deleted.
(JSC::DirectArguments::callee): Deleted.
(JSC::DirectArguments::argument): Deleted.
(JSC::DirectArguments::overrodeThings const): Deleted.
(JSC::DirectArguments::initModifiedArgumentsDescriptorIfNecessary): Deleted.
(JSC::DirectArguments::setModifiedArgumentDescriptor): Deleted.
(JSC::DirectArguments::isModifiedArgumentDescriptor): Deleted.
(JSC::DirectArguments::offsetOfCallee): Deleted.
(JSC::DirectArguments::offsetOfLength): Deleted.
(JSC::DirectArguments::offsetOfMinCapacity): Deleted.
(JSC::DirectArguments::offsetOfMappedArguments): Deleted.
(JSC::DirectArguments::offsetOfModifiedArgumentsDescriptor): Deleted.
(JSC::DirectArguments::storageOffset): Deleted.
(JSC::DirectArguments::offsetOfSlot): Deleted.
(JSC::DirectArguments::allocationSize): Deleted.
(JSC::DirectArguments::storage): Deleted.
* runtime/JSCast.h:
* runtime/JSGlobalLexicalEnvironment.h:
(JSC::JSGlobalLexicalEnvironment::create): Deleted.
(JSC::JSGlobalLexicalEnvironment::isEmpty const): Deleted.
(JSC::JSGlobalLexicalEnvironment::createStructure): Deleted.
(JSC::JSGlobalLexicalEnvironment::JSGlobalLexicalEnvironment): Deleted.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::finishCreation):
* runtime/JSMap.h:
(JSC::isJSMap): Deleted.
* runtime/JSModuleEnvironment.h:
(JSC::JSModuleEnvironment::create): Deleted.
(JSC::JSModuleEnvironment::createStructure): Deleted.
(JSC::JSModuleEnvironment::offsetOfModuleRecord): Deleted.
(JSC::JSModuleEnvironment::allocationSize): Deleted.
(JSC::JSModuleEnvironment::moduleRecord): Deleted.
(JSC::JSModuleEnvironment::moduleRecordSlot): Deleted.
* runtime/JSObject.cpp:
(JSC::canDoFastPutDirectIndex):
(JSC::JSObject::defineOwnIndexedProperty):
(JSC::JSObject::putDirectIndexSlowOrBeyondVectorLength):
* runtime/JSObject.h:
(JSC::JSFinalObject::allocationSize): Deleted.
(JSC::JSFinalObject::typeInfo): Deleted.
(JSC::JSFinalObject::defaultInlineCapacity): Deleted.
(JSC::JSFinalObject::maxInlineCapacity): Deleted.
(JSC::JSFinalObject::createStructure): Deleted.
(JSC::JSFinalObject::finishCreation): Deleted.
(JSC::JSFinalObject::JSFinalObject): Deleted.
(JSC::isJSFinalObject): Deleted.
* runtime/JSScope.cpp:
* runtime/JSScope.h:
* runtime/JSSegmentedVariableObject.cpp:
* runtime/JSSegmentedVariableObject.h:
* runtime/JSSet.h:
(JSC::isJSSet): Deleted.
* runtime/JSType.h:
* runtime/JSWeakMap.h:
(JSC::isJSWeakMap): Deleted.
* runtime/JSWeakSet.h:
(JSC::isJSWeakSet): Deleted.
* runtime/JSWithScope.h:
(JSC::JSWithScope::object): Deleted.
* runtime/MapConstructor.cpp:
(JSC::constructMap):
(JSC::mapPrivateFuncMapBucketHead):
* runtime/MapPrototype.cpp:
(JSC::getMap):
* runtime/NumberObject.cpp:
(JSC::NumberObject::finishCreation):
* runtime/NumberPrototype.cpp:
(JSC::toThisNumber):
(JSC::numberProtoFuncToExponential):
(JSC::numberProtoFuncToFixed):
(JSC::numberProtoFuncToPrecision):
(JSC::numberProtoFuncToString):
(JSC::numberProtoFuncToLocaleString):
(JSC::numberProtoFuncValueOf):
* runtime/ObjectConstructor.cpp:
(JSC::objectConstructorSeal):
(JSC::objectConstructorFreeze):
(JSC::objectConstructorIsSealed):
(JSC::objectConstructorIsFrozen):
* runtime/ProxyObject.cpp:
(JSC::ProxyObject::finishCreation):
* runtime/ScopedArguments.h:
(JSC::ScopedArguments::subspaceFor): Deleted.
(JSC::ScopedArguments::internalLength const): Deleted.
(JSC::ScopedArguments::length const): Deleted.
(JSC::ScopedArguments::isMappedArgument const): Deleted.
(JSC::ScopedArguments::isMappedArgumentInDFG const): Deleted.
(JSC::ScopedArguments::getIndexQuickly const): Deleted.
(JSC::ScopedArguments::setIndexQuickly): Deleted.
(JSC::ScopedArguments::callee): Deleted.
(JSC::ScopedArguments::overrodeThings const): Deleted.
(JSC::ScopedArguments::initModifiedArgumentsDescriptorIfNecessary): Deleted.
(JSC::ScopedArguments::setModifiedArgumentDescriptor): Deleted.
(JSC::ScopedArguments::isModifiedArgumentDescriptor): Deleted.
(JSC::ScopedArguments::offsetOfOverrodeThings): Deleted.
(JSC::ScopedArguments::offsetOfTotalLength): Deleted.
(JSC::ScopedArguments::offsetOfTable): Deleted.
(JSC::ScopedArguments::offsetOfScope): Deleted.
(JSC::ScopedArguments::overflowStorageOffset): Deleted.
(JSC::ScopedArguments::allocationSize): Deleted.
(JSC::ScopedArguments::overflowStorage const): Deleted.
* runtime/SetConstructor.cpp:
(JSC::constructSet):
(JSC::setPrivateFuncSetBucketHead):
* runtime/SetPrototype.cpp:
(JSC::getSet):
* runtime/StrictEvalActivation.h:
(JSC::StrictEvalActivation::create): Deleted.
(JSC::StrictEvalActivation::createStructure): Deleted.
* runtime/WeakMapPrototype.cpp:
(JSC::getWeakMap):
* runtime/WeakSetPrototype.cpp:
(JSC::getWeakSet):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@229362 268f45cc-cd09-0410-ab3c-d52691b4dbfc

33 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/runtime/ClonedArguments.h
Source/JavaScriptCore/runtime/DirectArguments.h
Source/JavaScriptCore/runtime/JSCast.h
Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSMap.h
Source/JavaScriptCore/runtime/JSModuleEnvironment.h
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSScope.cpp
Source/JavaScriptCore/runtime/JSScope.h
Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp
Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h
Source/JavaScriptCore/runtime/JSSet.h
Source/JavaScriptCore/runtime/JSType.h
Source/JavaScriptCore/runtime/JSWeakMap.h
Source/JavaScriptCore/runtime/JSWeakSet.h
Source/JavaScriptCore/runtime/JSWithScope.h
Source/JavaScriptCore/runtime/MapConstructor.cpp
Source/JavaScriptCore/runtime/MapPrototype.cpp
Source/JavaScriptCore/runtime/NumberObject.cpp
Source/JavaScriptCore/runtime/NumberPrototype.cpp
Source/JavaScriptCore/runtime/ObjectConstructor.cpp
Source/JavaScriptCore/runtime/ProxyObject.cpp
Source/JavaScriptCore/runtime/ScopedArguments.h
Source/JavaScriptCore/runtime/SetConstructor.cpp
Source/JavaScriptCore/runtime/SetPrototype.cpp
Source/JavaScriptCore/runtime/StrictEvalActivation.h
Source/JavaScriptCore/runtime/WeakMapPrototype.cpp
Source/JavaScriptCore/runtime/WeakSetPrototype.cpp

index 1d945b2..350ef91 100644 (file)
@@ -1,3 +1,141 @@
+2018-03-07  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC] Add more JSType based fast path for jsDynamicCast
+        https://bugs.webkit.org/show_bug.cgi?id=183403
+
+        Reviewed by Mark Lam.
+
+        We add more JSType based fast path for jsDynamicCast. Basically, we add miscellaneous JSTypes which
+        are used for jsDynamicCast in JSC, arguments types, and scope types.
+
+        We also add ClassInfo to JSScope and JSSegmentedVariableObject since they are used with jsDynamicCast.
+
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::setUpCall):
+        * runtime/ClonedArguments.h:
+        (JSC::ClonedArguments::specialsMaterialized const): Deleted.
+        * runtime/DirectArguments.h:
+        (JSC::DirectArguments::subspaceFor): Deleted.
+        (JSC::DirectArguments::internalLength const): Deleted.
+        (JSC::DirectArguments::length const): Deleted.
+        (JSC::DirectArguments::isMappedArgument const): Deleted.
+        (JSC::DirectArguments::isMappedArgumentInDFG const): Deleted.
+        (JSC::DirectArguments::getIndexQuickly const): Deleted.
+        (JSC::DirectArguments::setIndexQuickly): Deleted.
+        (JSC::DirectArguments::callee): Deleted.
+        (JSC::DirectArguments::argument): Deleted.
+        (JSC::DirectArguments::overrodeThings const): Deleted.
+        (JSC::DirectArguments::initModifiedArgumentsDescriptorIfNecessary): Deleted.
+        (JSC::DirectArguments::setModifiedArgumentDescriptor): Deleted.
+        (JSC::DirectArguments::isModifiedArgumentDescriptor): Deleted.
+        (JSC::DirectArguments::offsetOfCallee): Deleted.
+        (JSC::DirectArguments::offsetOfLength): Deleted.
+        (JSC::DirectArguments::offsetOfMinCapacity): Deleted.
+        (JSC::DirectArguments::offsetOfMappedArguments): Deleted.
+        (JSC::DirectArguments::offsetOfModifiedArgumentsDescriptor): Deleted.
+        (JSC::DirectArguments::storageOffset): Deleted.
+        (JSC::DirectArguments::offsetOfSlot): Deleted.
+        (JSC::DirectArguments::allocationSize): Deleted.
+        (JSC::DirectArguments::storage): Deleted.
+        * runtime/JSCast.h:
+        * runtime/JSGlobalLexicalEnvironment.h:
+        (JSC::JSGlobalLexicalEnvironment::create): Deleted.
+        (JSC::JSGlobalLexicalEnvironment::isEmpty const): Deleted.
+        (JSC::JSGlobalLexicalEnvironment::createStructure): Deleted.
+        (JSC::JSGlobalLexicalEnvironment::JSGlobalLexicalEnvironment): Deleted.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::finishCreation):
+        * runtime/JSMap.h:
+        (JSC::isJSMap): Deleted.
+        * runtime/JSModuleEnvironment.h:
+        (JSC::JSModuleEnvironment::create): Deleted.
+        (JSC::JSModuleEnvironment::createStructure): Deleted.
+        (JSC::JSModuleEnvironment::offsetOfModuleRecord): Deleted.
+        (JSC::JSModuleEnvironment::allocationSize): Deleted.
+        (JSC::JSModuleEnvironment::moduleRecord): Deleted.
+        (JSC::JSModuleEnvironment::moduleRecordSlot): Deleted.
+        * runtime/JSObject.cpp:
+        (JSC::canDoFastPutDirectIndex):
+        (JSC::JSObject::defineOwnIndexedProperty):
+        (JSC::JSObject::putDirectIndexSlowOrBeyondVectorLength):
+        * runtime/JSObject.h:
+        (JSC::JSFinalObject::allocationSize): Deleted.
+        (JSC::JSFinalObject::typeInfo): Deleted.
+        (JSC::JSFinalObject::defaultInlineCapacity): Deleted.
+        (JSC::JSFinalObject::maxInlineCapacity): Deleted.
+        (JSC::JSFinalObject::createStructure): Deleted.
+        (JSC::JSFinalObject::finishCreation): Deleted.
+        (JSC::JSFinalObject::JSFinalObject): Deleted.
+        (JSC::isJSFinalObject): Deleted.
+        * runtime/JSScope.cpp:
+        * runtime/JSScope.h:
+        * runtime/JSSegmentedVariableObject.cpp:
+        * runtime/JSSegmentedVariableObject.h:
+        * runtime/JSSet.h:
+        (JSC::isJSSet): Deleted.
+        * runtime/JSType.h:
+        * runtime/JSWeakMap.h:
+        (JSC::isJSWeakMap): Deleted.
+        * runtime/JSWeakSet.h:
+        (JSC::isJSWeakSet): Deleted.
+        * runtime/JSWithScope.h:
+        (JSC::JSWithScope::object): Deleted.
+        * runtime/MapConstructor.cpp:
+        (JSC::constructMap):
+        (JSC::mapPrivateFuncMapBucketHead):
+        * runtime/MapPrototype.cpp:
+        (JSC::getMap):
+        * runtime/NumberObject.cpp:
+        (JSC::NumberObject::finishCreation):
+        * runtime/NumberPrototype.cpp:
+        (JSC::toThisNumber):
+        (JSC::numberProtoFuncToExponential):
+        (JSC::numberProtoFuncToFixed):
+        (JSC::numberProtoFuncToPrecision):
+        (JSC::numberProtoFuncToString):
+        (JSC::numberProtoFuncToLocaleString):
+        (JSC::numberProtoFuncValueOf):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorSeal):
+        (JSC::objectConstructorFreeze):
+        (JSC::objectConstructorIsSealed):
+        (JSC::objectConstructorIsFrozen):
+        * runtime/ProxyObject.cpp:
+        (JSC::ProxyObject::finishCreation):
+        * runtime/ScopedArguments.h:
+        (JSC::ScopedArguments::subspaceFor): Deleted.
+        (JSC::ScopedArguments::internalLength const): Deleted.
+        (JSC::ScopedArguments::length const): Deleted.
+        (JSC::ScopedArguments::isMappedArgument const): Deleted.
+        (JSC::ScopedArguments::isMappedArgumentInDFG const): Deleted.
+        (JSC::ScopedArguments::getIndexQuickly const): Deleted.
+        (JSC::ScopedArguments::setIndexQuickly): Deleted.
+        (JSC::ScopedArguments::callee): Deleted.
+        (JSC::ScopedArguments::overrodeThings const): Deleted.
+        (JSC::ScopedArguments::initModifiedArgumentsDescriptorIfNecessary): Deleted.
+        (JSC::ScopedArguments::setModifiedArgumentDescriptor): Deleted.
+        (JSC::ScopedArguments::isModifiedArgumentDescriptor): Deleted.
+        (JSC::ScopedArguments::offsetOfOverrodeThings): Deleted.
+        (JSC::ScopedArguments::offsetOfTotalLength): Deleted.
+        (JSC::ScopedArguments::offsetOfTable): Deleted.
+        (JSC::ScopedArguments::offsetOfScope): Deleted.
+        (JSC::ScopedArguments::overflowStorageOffset): Deleted.
+        (JSC::ScopedArguments::allocationSize): Deleted.
+        (JSC::ScopedArguments::overflowStorage const): Deleted.
+        * runtime/SetConstructor.cpp:
+        (JSC::constructSet):
+        (JSC::setPrivateFuncSetBucketHead):
+        * runtime/SetPrototype.cpp:
+        (JSC::getSet):
+        * runtime/StrictEvalActivation.h:
+        (JSC::StrictEvalActivation::create): Deleted.
+        (JSC::StrictEvalActivation::createStructure): Deleted.
+        * runtime/WeakMapPrototype.cpp:
+        (JSC::getWeakMap):
+        * runtime/WeakSetPrototype.cpp:
+        (JSC::getWeakSet):
+
 2018-03-07  Dominik Infuehr  <dinfuehr@igalia.com>
 
         [ARM] offlineasm: fix indentation in armOpcodeReversedOperands
index b5de023..4122ca9 100644 (file)
@@ -938,14 +938,14 @@ SlowPathReturnType JIT_OPERATION operationLinkCall(ExecState* execCallee, CallLi
     JSValue calleeAsValue = execCallee->guaranteedJSValueCallee();
     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
     if (!calleeAsFunctionCell) {
-        if (calleeAsValue.isCell() && calleeAsValue.asCell()->type() == InternalFunctionType) {
+        if (auto* internalFunction = jsDynamicCast<InternalFunction*>(*vm, calleeAsValue)) {
             MacroAssemblerCodePtr codePtr = vm->getCTIInternalFunctionTrampolineFor(kind);
             RELEASE_ASSERT(!!codePtr);
 
             if (!callLinkInfo->seenOnce())
                 callLinkInfo->setSeen();
             else
-                linkFor(execCallee, *callLinkInfo, nullptr, asObject(calleeAsValue), codePtr);
+                linkFor(execCallee, *callLinkInfo, nullptr, internalFunction, codePtr);
 
             return encodeResult(codePtr.executableAddress(), reinterpret_cast<void*>(callLinkInfo->callMode() == CallMode::Tail ? ReuseTheFrame : KeepTheFrame));
         }
@@ -1060,7 +1060,7 @@ inline SlowPathReturnType virtualForWithFunction(
     JSValue calleeAsValue = execCallee->guaranteedJSValueCallee();
     calleeAsFunctionCell = getJSFunction(calleeAsValue);
     if (UNLIKELY(!calleeAsFunctionCell)) {
-        if (calleeAsValue.isCell() && calleeAsValue.asCell()->type() == InternalFunctionType) {
+        if (jsDynamicCast<InternalFunction*>(*vm, calleeAsValue)) {
             MacroAssemblerCodePtr codePtr = vm->getCTIInternalFunctionTrampolineFor(kind);
             ASSERT(!!codePtr);
             return encodeResult(codePtr.executableAddress(), reinterpret_cast<void*>(callLinkInfo->callMode() == CallMode::Tail ? ReuseTheFrame : KeepTheFrame));
index add62b9..a90cb9e 100644 (file)
@@ -1373,8 +1373,7 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
     
     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
     if (!calleeAsFunctionCell) {
-        if (calleeAsValue.isCell() && calleeAsValue.asCell()->type() == InternalFunctionType) {
-            auto* internalFunction = jsCast<InternalFunction*>(calleeAsValue.asCell());
+        if (auto* internalFunction = jsDynamicCast<InternalFunction*>(vm, calleeAsValue)) {
             MacroAssemblerCodePtr codePtr = vm.getCTIInternalFunctionTrampolineFor(kind);
             ASSERT(!!codePtr);
 
index 7601c5c..97d2ae6 100644 (file)
@@ -37,7 +37,7 @@ namespace JSC {
 // properties of the object are populated. The only reason why we need a special class is to make
 // the object claim to be "Arguments" from a toString standpoint, and to avoid materializing the
 // caller/callee/@@iterator properties unless someone asks for them.
-class ClonedArguments : public JSNonFinalObject {
+class ClonedArguments final : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
     static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
index 1606f1a..d3a15a5 100644 (file)
@@ -41,7 +41,7 @@ namespace JSC {
 //
 // To speed allocation, this object will hold all of the arguments in-place. The arguments as well
 // as a table of flags saying which arguments were overridden.
-class DirectArguments : public GenericArguments<DirectArguments> {
+class DirectArguments final : public GenericArguments<DirectArguments> {
 private:
     DirectArguments(VM&, Structure*, unsigned length, unsigned capacity);
     
index 4fe2b9f..1857f68 100644 (file)
@@ -48,10 +48,27 @@ inline To jsCast(JSValue from)
 // Specific type overloads.
 #define FOR_EACH_JS_DYNAMIC_CAST_JS_TYPE_OVERLOAD(macro) \
     macro(JSObject, JSType::ObjectType, JSType::LastJSCObjectType) \
+    macro(JSFinalObject, JSType::FinalObjectType, JSType::FinalObjectType) \
     macro(JSFunction, JSType::JSFunctionType, JSType::JSFunctionType) \
     macro(InternalFunction, JSType::InternalFunctionType, JSType::InternalFunctionType) \
     macro(JSArray, JSType::ArrayType, JSType::DerivedArrayType) \
     macro(JSArrayBufferView, FirstTypedArrayType, LastTypedArrayType) \
+    macro(JSSet, JSType::JSSetType, JSType::JSSetType) \
+    macro(JSMap, JSType::JSMapType, JSType::JSMapType) \
+    macro(JSWeakSet, JSType::JSWeakSetType, JSType::JSWeakSetType) \
+    macro(JSWeakMap, JSType::JSWeakMapType, JSType::JSWeakMapType) \
+    macro(NumberObject, JSType::NumberObjectType, JSType::NumberObjectType) \
+    macro(ProxyObject, JSType::ProxyObjectType, JSType::ProxyObjectType) \
+    macro(DirectArguments, JSType::DirectArgumentsType, JSType::DirectArgumentsType) \
+    macro(ScopedArguments, JSType::ScopedArgumentsType, JSType::ScopedArgumentsType) \
+    macro(ClonedArguments, JSType::ClonedArgumentsType, JSType::ClonedArgumentsType) \
+    macro(JSGlobalObject, JSType::GlobalObjectType, JSType::GlobalObjectType) \
+    macro(JSGlobalLexicalEnvironment, JSType::GlobalLexicalEnvironmentType, JSType::GlobalLexicalEnvironmentType) \
+    macro(JSSegmentedVariableObject, JSType::GlobalObjectType, JSType::GlobalLexicalEnvironmentType) \
+    macro(JSModuleEnvironment, JSType::ModuleEnvironmentType, JSType::ModuleEnvironmentType) \
+    macro(JSLexicalEnvironment, JSType::LexicalEnvironmentType, JSType::ModuleEnvironmentType) \
+    macro(JSSymbolTableObject, JSType::GlobalObjectType, JSType::ModuleEnvironmentType) \
+    macro(JSScope, JSType::GlobalObjectType, JSType::WithScopeType) \
 
 
 // Forward declare the classes because they may not already exist.
index 1e9d9ee..3bdaf4f 100644 (file)
 
 namespace JSC {
 
-class JSGlobalLexicalEnvironment : public JSSegmentedVariableObject {
+class JSGlobalLexicalEnvironment final : public JSSegmentedVariableObject {
 
 public:
-    typedef JSSegmentedVariableObject Base;
+    using Base = JSSegmentedVariableObject;
 
     static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
 
index 734f6ae..461e003 100644 (file)
@@ -1599,6 +1599,7 @@ void JSGlobalObject::finishCreation(VM& vm)
     m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
     init(vm);
     setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, getPrototypeDirect(vm), PureForwardingProxyType), this));
+    ASSERT(type() == GlobalObjectType);
 }
 
 void JSGlobalObject::finishCreation(VM& vm, JSObject* thisValue)
@@ -1608,6 +1609,7 @@ void JSGlobalObject::finishCreation(VM& vm, JSObject* thisValue)
     m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
     init(vm);
     setGlobalThis(vm, thisValue);
+    ASSERT(type() == GlobalObjectType);
 }
 
 } // namespace JSC
index 9c9d506..f0ebb54 100644 (file)
@@ -66,16 +66,6 @@ private:
     static String toStringName(const JSObject*, ExecState*);
 };
 
-inline bool isJSMap(JSCell* from)
-{
-    static_assert(std::is_final<JSMap>::value, "");
-    return from->type() == JSMapType;
-}
-
-inline bool isJSMap(JSValue from)
-{
-    static_assert(std::is_final<JSMap>::value, "");
-    return from.isCell() && from.asCell()->type() == JSMapType;
-}
+static_assert(std::is_final<JSMap>::value, "Required for JSType based casting");
 
 } // namespace JSC
index c3fd16f..20440ee 100644 (file)
@@ -35,11 +35,11 @@ namespace JSC {
 class AbstractModuleRecord;
 class Register;
 
-class JSModuleEnvironment : public JSLexicalEnvironment {
+class JSModuleEnvironment final : public JSLexicalEnvironment {
     friend class JIT;
     friend class LLIntOffsetsExtractor;
 public:
-    typedef JSLexicalEnvironment Base;
+    using Base = JSLexicalEnvironment;
     static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
 
     static JSModuleEnvironment* create(VM&, Structure*, JSScope*, SymbolTable*, JSValue initialValue, AbstractModuleRecord*);
index ef0e22f..2525913 100644 (file)
@@ -2407,10 +2407,10 @@ bool JSObject::putIndexedDescriptor(ExecState* exec, SparseArrayEntry* entryInMa
     return true;
 }
 
-ALWAYS_INLINE static bool canDoFastPutDirectIndex(JSObject* object)
+ALWAYS_INLINE static bool canDoFastPutDirectIndex(VM& vm, JSObject* object)
 {
     return isJSArray(object)
-        || isJSFinalObject(object)
+        || jsDynamicCast<JSFinalObject*>(vm, object)
         || TypeInfo::isArgumentsType(object->type());
 }
 
@@ -2427,7 +2427,7 @@ bool JSObject::defineOwnIndexedProperty(ExecState* exec, unsigned index, const P
         // FIXME: this will pessimistically assume that if attributes are missing then they'll default to false
         // however if the property currently exists missing attributes will override from their current 'true'
         // state (i.e. defineOwnProperty could be used to set a value without needing to entering 'SparseMode').
-        if (!descriptor.attributes() && descriptor.value() && canDoFastPutDirectIndex(this)) {
+        if (!descriptor.attributes() && descriptor.value() && canDoFastPutDirectIndex(vm, this)) {
             ASSERT(!descriptor.isAccessorDescriptor());
             scope.release();
             return putDirectIndex(exec, index, descriptor.value(), 0, throwException ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
@@ -2881,7 +2881,7 @@ bool JSObject::putDirectIndexSlowOrBeyondVectorLength(ExecState* exec, unsigned
 {
     VM& vm = exec->vm();
     
-    if (!canDoFastPutDirectIndex(this)) {
+    if (!canDoFastPutDirectIndex(vm, this)) {
         PropertyDescriptor descriptor;
         descriptor.setDescriptor(value, attributes);
         return methodTable(vm)->defineOwnProperty(this, exec, Identifier::from(exec, i), descriptor, mode == PutDirectIndexShouldThrow);
index b4d8b1a..3b50821 100644 (file)
@@ -1096,9 +1096,9 @@ protected:
 
 class JSFinalObject;
 
-// JSFinalObject is a type of JSObject that contains sufficent internal
-// storage to fully make use of the colloctor cell containing it.
-class JSFinalObject : public JSObject {
+// JSFinalObject is a type of JSObject that contains sufficient internal
+// storage to fully make use of the collector cell containing it.
+class JSFinalObject final : public JSObject {
     friend class JSObject;
 
 public:
@@ -1195,16 +1195,6 @@ inline JSFinalObject* JSFinalObject::create(VM& vm, Structure* structure)
     return finalObject;
 }
 
-inline bool isJSFinalObject(JSCell* cell)
-{
-    return cell->type() == FinalObjectType;
-}
-
-inline bool isJSFinalObject(JSValue value)
-{
-    return value.isCell() && isJSFinalObject(value.asCell());
-}
-
 inline size_t JSObject::offsetOfInlineStorage()
 {
     return sizeof(JSObject);
index c9df6ce..3f7f3f1 100644 (file)
@@ -39,6 +39,8 @@ namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSScope);
 
+const ClassInfo JSScope::s_info = { "Scope", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSScope) };
+
 void JSScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSScope* thisObject = jsCast<JSScope*>(cell);
index d221bc0..6f239c5 100644 (file)
@@ -37,9 +37,11 @@ class WatchpointSet;
 
 class JSScope : public JSNonFinalObject {
 public:
-    typedef JSNonFinalObject Base;
+    using Base = JSNonFinalObject;
     static const unsigned StructureFlags = Base::StructureFlags | OverridesToThis;
 
+    DECLARE_EXPORT_INFO;
+
     friend class LLIntOffsetsExtractor;
     static size_t offsetOfNext();
 
index b7487f5..e560369 100644 (file)
@@ -34,6 +34,8 @@
 
 namespace JSC {
 
+const ClassInfo JSSegmentedVariableObject::s_info = { "SegmentedVariableObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSegmentedVariableObject) };
+
 ScopeOffset JSSegmentedVariableObject::findVariableIndex(void* variableAddress)
 {
     ConcurrentJSLocker locker(m_lock);
index b92fd7f..ae30db7 100644 (file)
@@ -54,7 +54,9 @@ class JSSegmentedVariableObject : public JSSymbolTableObject {
     friend class LLIntOffsetsExtractor;
 
 public:
-    typedef JSSymbolTableObject Base;
+    using Base = JSSymbolTableObject;
+
+    DECLARE_INFO;
 
     bool isValidScopeOffset(ScopeOffset offset)
     {
index 8afcde7..eb7a49f 100644 (file)
@@ -71,16 +71,6 @@ private:
     static String toStringName(const JSObject*, ExecState*);
 };
 
-inline bool isJSSet(JSCell* from)
-{
-    static_assert(std::is_final<JSSet>::value, "");
-    return from->type() == JSSetType;
-}
-
-inline bool isJSSet(JSValue from)
-{
-    static_assert(std::is_final<JSSet>::value, "");
-    return from.isCell() && from.asCell()->type() == JSSetType;
-}
+static_assert(std::is_final<JSSet>::value, "Required for JSType based casting");
 
 } // namespace JSC
index c882218..b3f7cd2 100644 (file)
@@ -61,7 +61,6 @@ enum JSType : uint8_t {
     ErrorInstanceType,
     PureForwardingProxyType,
     ImpureProxyType,
-    WithScopeType,
     DirectArgumentsType,
     ScopedArgumentsType,
     ClonedArgumentsType,
@@ -86,13 +85,21 @@ enum JSType : uint8_t {
 
     GetterSetterType,
 
+    // JSScope <- JSWithScope
+    //         <- StrictEvalActivation
+    //         <- JSSymbolTableObject  <- JSLexicalEnvironment      <- JSModuleEnvironment
+    //                                 <- JSSegmentedVariableObject <- JSGlobalLexicalEnvironment
+    //                                                              <- JSGlobalObject
+    // Start JSScope types.
     // Start environment record types.
     GlobalObjectType,
-    LexicalEnvironmentType,
     GlobalLexicalEnvironmentType,
+    LexicalEnvironmentType,
     ModuleEnvironmentType,
     StrictEvalActivationType,
     // End environment record types.
+    WithScopeType,
+    // End JSScope types.
 
     RegExpObjectType,
     ProxyObjectType,
index 8de8d26..814ac84 100644 (file)
@@ -62,16 +62,6 @@ private:
     static String toStringName(const JSObject*, ExecState*);
 };
 
-inline bool isJSWeakMap(JSCell* from)
-{
-    static_assert(std::is_final<JSWeakMap>::value, "");
-    return from->type() == JSWeakMapType;
-}
-
-inline bool isJSWeakMap(JSValue from)
-{
-    static_assert(std::is_final<JSWeakMap>::value, "");
-    return from.isCell() && from.asCell()->type() == JSWeakMapType;
-}
+static_assert(std::is_final<JSWeakMap>::value, "Required for JSType based casting");
 
 } // namespace JSC
index 6b9a018..1e02072 100644 (file)
@@ -57,16 +57,6 @@ private:
     static String toStringName(const JSObject*, ExecState*);
 };
 
-inline bool isJSWeakSet(JSCell* from)
-{
-    static_assert(std::is_final<JSWeakSet>::value, "");
-    return from->type() == JSWeakSetType;
-}
-
-inline bool isJSWeakSet(JSValue from)
-{
-    static_assert(std::is_final<JSWeakSet>::value, "");
-    return from.isCell() && from.asCell()->type() == JSWeakSetType;
-}
+static_assert(std::is_final<JSWeakSet>::value, "Required for JSType based casting");
 
 } // namespace JSC
index 2847bd8..1d6d5ea 100644 (file)
@@ -29,9 +29,9 @@
 
 namespace JSC {
 
-class JSWithScope : public JSScope {
+class JSWithScope final : public JSScope {
 public:
-    typedef JSScope Base;
+    using Base = JSScope;
 
     JS_EXPORT_PRIVATE static JSWithScope* create(VM&, JSGlobalObject*, JSScope* next, JSObject*);
 
index 3914f2c..14e273e 100644 (file)
@@ -77,8 +77,7 @@ static EncodedJSValue JSC_HOST_CALL constructMap(ExecState* exec)
         return JSValue::encode(JSMap::create(exec, vm, mapStructure));
     }
 
-    if (isJSMap(iterable)) {
-        JSMap* iterableMap = jsCast<JSMap*>(iterable);
+    if (auto* iterableMap = jsDynamicCast<JSMap*>(vm, iterable)) {
         if (iterableMap->canCloneFastAndNonObservable(mapStructure)) {
             scope.release();
             return JSValue::encode(iterableMap->clone(exec, vm, mapStructure));
@@ -123,7 +122,7 @@ static EncodedJSValue JSC_HOST_CALL constructMap(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL mapPrivateFuncMapBucketHead(ExecState* exec)
 {
-    ASSERT(isJSMap(exec->argument(0)));
+    ASSERT(jsDynamicCast<JSMap*>(exec->vm(), exec->argument(0)));
     JSMap* map = jsCast<JSMap*>(exec->uncheckedArgument(0));
     auto* head = map->head();
     ASSERT(head);
index ea9a76b..53568b7 100644 (file)
@@ -89,8 +89,9 @@ ALWAYS_INLINE static JSMap* getMap(CallFrame* callFrame, JSValue thisValue)
         return nullptr;
     }
 
-    if (LIKELY(thisValue.asCell()->type() == JSMapType))
-        return jsCast<JSMap*>(thisValue);
+    auto* map = jsDynamicCast<JSMap*>(vm, thisValue.asCell());
+    if (LIKELY(map))
+        return map;
     throwTypeError(callFrame, scope, ASCIILiteral("Map operation called on non-Map object"));
     return nullptr;
 }
index d37f4e5..b76e247 100644 (file)
@@ -41,6 +41,7 @@ void NumberObject::finishCreation(VM& vm)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(vm, info()));
+    ASSERT(type() == NumberObjectType);
 }
 
 NumberObject* constructNumber(ExecState* exec, JSGlobalObject* globalObject, JSValue number)
index fd764ac..696668c 100644 (file)
@@ -89,7 +89,7 @@ void NumberPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
 
 // ------------------------------ Functions ---------------------------
 
-static ALWAYS_INLINE bool toThisNumber(JSValue thisValue, double& x)
+static ALWAYS_INLINE bool toThisNumber(VM& vm, JSValue thisValue, double& x)
 {
     if (thisValue.isInt32()) {
         x = thisValue.asInt32();
@@ -100,9 +100,9 @@ static ALWAYS_INLINE bool toThisNumber(JSValue thisValue, double& x)
         x = thisValue.asDouble();
         return true;
     }
-    
-    if (thisValue.isCell() && thisValue.asCell()->type() == NumberObjectType) {
-        x = static_cast<const NumberObject*>(thisValue.asCell())->internalValue().asNumber();
+
+    if (auto* numberObject = jsDynamicCast<NumberObject*>(vm, thisValue)) {
+        x = numberObject->internalValue().asNumber();
         return true;
     }
 
@@ -407,7 +407,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
     auto scope = DECLARE_THROW_SCOPE(vm);
 
     double x;
-    if (!toThisNumber(exec->thisValue(), x))
+    if (!toThisNumber(vm, exec->thisValue(), x))
         return throwVMTypeError(exec, scope);
 
     // Perform ToInteger on the argument before remaining steps.
@@ -444,7 +444,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
     auto scope = DECLARE_THROW_SCOPE(vm);
 
     double x;
-    if (!toThisNumber(exec->thisValue(), x))
+    if (!toThisNumber(vm, exec->thisValue(), x))
         return throwVMTypeError(exec, scope);
 
     // Get the argument. 
@@ -482,7 +482,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
     auto scope = DECLARE_THROW_SCOPE(vm);
 
     double x;
-    if (!toThisNumber(exec->thisValue(), x))
+    if (!toThisNumber(vm, exec->thisValue(), x))
         return throwVMTypeError(exec, scope);
 
     // Perform ToInteger on the argument before remaining steps.
@@ -580,7 +580,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* state)
     auto scope = DECLARE_THROW_SCOPE(vm);
 
     double doubleValue;
-    if (!toThisNumber(state->thisValue(), doubleValue))
+    if (!toThisNumber(vm, state->thisValue(), doubleValue))
         return throwVMTypeError(state, scope);
 
     auto radix = extractToStringRadixArgument(state, state->argument(0), scope);
@@ -595,7 +595,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState* exec)
     auto scope = DECLARE_THROW_SCOPE(vm);
 
     double x;
-    if (!toThisNumber(exec->thisValue(), x))
+    if (!toThisNumber(vm, exec->thisValue(), x))
         return throwVMTypeError(exec, scope);
 
     return JSValue::encode(jsNumber(x).toString(exec));
@@ -608,7 +608,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState* exec)
 
     double x;
     JSValue thisValue = exec->thisValue();
-    if (!toThisNumber(thisValue, x))
+    if (!toThisNumber(vm, thisValue, x))
         return throwVMTypeError(exec, scope, WTF::makeString("thisNumberValue called on incompatible ", asString(jsTypeStringForValue(exec, thisValue))->value(exec)));
     return JSValue::encode(jsNumber(x));
 }
index b737949..22d6459 100644 (file)
@@ -715,7 +715,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec)
         return JSValue::encode(obj);
     JSObject* object = asObject(obj);
 
-    if (isJSFinalObject(object) && !hasIndexedProperties(object->indexingType())) {
+    if (jsDynamicCast<JSFinalObject*>(vm, object) && !hasIndexedProperties(object->indexingType())) {
         object->seal(vm);
         return JSValue::encode(obj);
     }
@@ -735,7 +735,7 @@ JSObject* objectConstructorFreeze(ExecState* exec, JSObject* object)
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (isJSFinalObject(object) && !hasIndexedProperties(object->indexingType())) {
+    if (jsDynamicCast<JSFinalObject*>(vm, object) && !hasIndexedProperties(object->indexingType())) {
         object->freeze(vm);
         return object;
     }
@@ -782,7 +782,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState* exec)
     JSObject* object = asObject(obj);
 
     // Quick check for final objects.
-    if (isJSFinalObject(object) && !hasIndexedProperties(object->indexingType()))
+    if (jsDynamicCast<JSFinalObject*>(vm, object) && !hasIndexedProperties(object->indexingType()))
         return JSValue::encode(jsBoolean(object->isSealed(vm)));
 
     // 2. Return ? TestIntegrityLevel(O, "sealed").
@@ -800,7 +800,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec)
     JSObject* object = asObject(obj);
 
     // Quick check for final objects.
-    if (isJSFinalObject(object) && !hasIndexedProperties(object->indexingType()))
+    if (jsDynamicCast<JSFinalObject*>(vm, object) && !hasIndexedProperties(object->indexingType()))
         return JSValue::encode(jsBoolean(object->isFrozen(vm)));
 
     // 2. Return ? TestIntegrityLevel(O, "frozen").
index c1d7ab8..5c3ee5e 100644 (file)
@@ -87,6 +87,7 @@ void ProxyObject::finishCreation(VM& vm, ExecState* exec, JSValue target, JSValu
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
     Base::finishCreation(vm);
+    ASSERT(type() == ProxyObjectType);
     if (!target.isObject()) {
         throwTypeError(exec, scope, ASCIILiteral("A Proxy's 'target' should be an Object"));
         return;
index 66f5efe..6518831 100644 (file)
@@ -36,7 +36,7 @@ namespace JSC {
 // object will store the overflow arguments, if there are any. This object will use the symbol
 // table's ScopedArgumentsTable and the activation, or its overflow storage, to handle all indexed
 // lookups.
-class ScopedArguments : public GenericArguments<ScopedArguments> {
+class ScopedArguments final : public GenericArguments<ScopedArguments> {
 private:
     ScopedArguments(VM&, Structure*, unsigned totalLength);
     void finishCreation(VM&, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*);
index e7b3dc2..713f6de 100644 (file)
@@ -77,8 +77,7 @@ static EncodedJSValue JSC_HOST_CALL constructSet(ExecState* exec)
         return JSValue::encode(JSSet::create(exec, vm, setStructure));
     }
 
-    if (isJSSet(iterable)) {
-        JSSet* iterableSet = jsCast<JSSet*>(iterable);
+    if (auto* iterableSet = jsDynamicCast<JSSet*>(vm, iterable)) {
         if (iterableSet->canCloneFastAndNonObservable(setStructure)) {
             scope.release();
             return JSValue::encode(iterableSet->clone(exec, vm, setStructure));
@@ -109,7 +108,7 @@ static EncodedJSValue JSC_HOST_CALL constructSet(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL setPrivateFuncSetBucketHead(ExecState* exec)
 {
-    ASSERT(isJSSet(exec->argument(0)));
+    ASSERT(jsDynamicCast<JSSet*>(exec->vm(), exec->argument(0)));
     JSSet* set = jsCast<JSSet*>(exec->uncheckedArgument(0));
     auto* head = set->head();
     ASSERT(head);
index 5db52c2..2934396 100644 (file)
@@ -86,8 +86,9 @@ ALWAYS_INLINE static JSSet* getSet(CallFrame* callFrame, JSValue thisValue)
         throwVMError(callFrame, scope, createNotAnObjectError(callFrame, thisValue));
         return nullptr;
     }
-    if (LIKELY(thisValue.asCell()->type() == JSSetType))
-        return jsCast<JSSet*>(thisValue);
+    auto* set = jsDynamicCast<JSSet*>(vm, thisValue.asCell());
+    if (LIKELY(set))
+        return set;
     throwTypeError(callFrame, scope, ASCIILiteral("Set operation called on non-Set object"));
     return nullptr;
 }
index 740ca32..2be09f5 100644 (file)
 
 namespace JSC {
 
-class StrictEvalActivation : public JSScope {
+class StrictEvalActivation final : public JSScope {
 public:
-    typedef JSScope Base;
-    static const unsigned StructureFlags = Base::StructureFlags;
+    using Base = JSScope;
 
     static StrictEvalActivation* create(ExecState* exec, JSScope* currentScope)
     {
index f607636..55ca028 100644 (file)
@@ -62,8 +62,9 @@ ALWAYS_INLINE static JSWeakMap* getWeakMap(CallFrame* callFrame, JSValue value)
         return nullptr;
     }
 
-    if (LIKELY(isJSWeakMap(asObject(value))))
-        return jsCast<JSWeakMap*>(value);
+    auto* map = jsDynamicCast<JSWeakMap*>(vm, asObject(value));
+    if (LIKELY(map))
+        return map;
 
     throwTypeError(callFrame, scope, WTF::ASCIILiteral("Called WeakMap function on a non-WeakMap object"));
     return nullptr;
index 6486d21..1413ae6 100644 (file)
@@ -60,8 +60,9 @@ ALWAYS_INLINE static JSWeakSet* getWeakSet(CallFrame* callFrame, JSValue value)
         return nullptr;
     }
 
-    if (LIKELY(isJSWeakSet(asObject(value))))
-        return jsCast<JSWeakSet*>(value);
+    auto* set = jsDynamicCast<JSWeakSet*>(vm, asObject(value));
+    if (LIKELY(set))
+        return set;
 
     throwTypeError(callFrame, scope, WTF::ASCIILiteral("Called WeakSet function on a non-WeakSet object"));
     return nullptr;