Skip to content

Commit

Permalink
[MERGE #4118 @pleath] Share types (i.e., allow PathTypeHandlers) for …
Browse files Browse the repository at this point in the history
…properties with non-standard attributes (non-writable, etc.).

Merge pull request #4118 from pleath:sharetypes-m

This change draws on Kount Veluri's work on behalf of native fields. It adds a wrinkle to the type path mechanism, replacing the PropertyId successor map key with a key that munges PropertyId and attributes. The way is paved for sharing types with getter/setters, deleted properties, and native values. When a property's attributes are changed/set, the type path is branched starting with the type that precedes the one that introduced the property.
  • Loading branch information
pleath committed Nov 3, 2017
2 parents 1aeea11 + 2f81075 commit e1b4272
Show file tree
Hide file tree
Showing 7 changed files with 1,479 additions and 271 deletions.
2 changes: 1 addition & 1 deletion lib/Jsrt/JsrtExternalObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ JsrtExternalType::JsrtExternalType(Js::ScriptContext* scriptContext, JsFinalizeC
Js::TypeIds_Object,
scriptContext->GetLibrary()->GetObjectPrototype(),
nullptr,
Js::SimplePathTypeHandler::New(scriptContext, scriptContext->GetLibrary()->GetRootPath(), 0, 0, 0, true, true),
Js::SimplePathTypeHandlerNoAttr::New(scriptContext, scriptContext->GetLibrary()->GetRootPath(), 0, 0, 0, true, true),
true,
true)
, jsFinalizeCallback(finalizeCallback)
Expand Down
2 changes: 0 additions & 2 deletions lib/Runtime/Debug/TTSnapObjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,6 @@ namespace TTD

if(snpObject->SnapType->HasNoEnumerableProperties != obj->GetDynamicType()->GetHasNoEnumerableProperties())
{
TTDAssert(!obj->GetDynamicType()->GetIsShared(), "This is shared so we are mucking something up.");

obj->GetDynamicType()->SetHasNoEnumerableProperties(snpObject->SnapType->HasNoEnumerableProperties);
}
}
Expand Down
50 changes: 25 additions & 25 deletions lib/Runtime/Library/JavascriptLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ namespace Js

#define INIT_SIMPLE_TYPE(field, typeId, prototype) \
field = DynamicType::New(scriptContext, typeId, prototype, nullptr, \
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true)
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true)

INIT_SIMPLE_TYPE(activationObjectType, TypeIds_ActivationObject, nullValue);
INIT_SIMPLE_TYPE(arrayType, TypeIds_Array, arrayPrototype);
Expand Down Expand Up @@ -523,7 +523,7 @@ namespace Js

// Initialize Date types
dateType = DynamicType::New(scriptContext, TypeIds_Date, datePrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
variantDateType = StaticType::New(scriptContext, TypeIds_VariantDate, nullValue, nullptr);

anonymousFunctionTypeHandler = NullTypeHandler<false>::GetDefaultInstance();
Expand Down Expand Up @@ -566,7 +566,7 @@ namespace Js
else
{
boundFunctionType = DynamicType::New(scriptContext, TypeIds_Function, functionPrototype, BoundFunction::NewInstance,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
}
crossSiteDeferredPrototypeFunctionType = CreateDeferredPrototypeFunctionTypeNoProfileThunk(
scriptContext->CurrentCrossSiteThunk, true /*isShared*/);
Expand Down Expand Up @@ -627,8 +627,8 @@ namespace Js
// Initialize Object types
for (int16 i = 0; i < PreInitializedObjectTypeCount; i++)
{
SimplePathTypeHandler * typeHandler =
SimplePathTypeHandler::New(
SimplePathTypeHandlerNoAttr * typeHandler =
SimplePathTypeHandlerNoAttr::New(
scriptContext,
this->GetRootPath(),
0,
Expand All @@ -641,8 +641,8 @@ namespace Js
}
for (int16 i = 0; i < PreInitializedObjectTypeCount; i++)
{
SimplePathTypeHandler * typeHandler =
SimplePathTypeHandler::New(
SimplePathTypeHandlerNoAttr * typeHandler =
SimplePathTypeHandlerNoAttr::New(
scriptContext,
this->GetRootPath(),
0,
Expand All @@ -655,15 +655,15 @@ namespace Js
DynamicType::New(scriptContext, TypeIds_Object, objectPrototype, nullptr, typeHandler, true, true);
}

SimplePathTypeHandler * typeHandler = SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true);
SimplePathTypeHandlerNoAttr * typeHandler = SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true);
nullPrototypeObjectType = DynamicType::New(scriptContext, TypeIds_Object, nullValue, nullptr, typeHandler, true, true);

// Initialize regex types
TypePath *const regexResultPath = TypePath::New(recycler);
regexResultPath->Add(BuiltInPropertyRecords::input);
regexResultPath->Add(BuiltInPropertyRecords::index);
regexResultType = DynamicType::New(scriptContext, TypeIds_Array, arrayPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, regexResultPath, regexResultPath->GetPathLength(), JavascriptRegularExpressionResult::InlineSlotCount, sizeof(JavascriptArray), true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, regexResultPath, regexResultPath->GetPathLength(), JavascriptRegularExpressionResult::InlineSlotCount, sizeof(JavascriptArray), true, true), true, true);

// Initialize string types
// static type is handled under StringCache.h
Expand All @@ -673,33 +673,33 @@ namespace Js
throwErrorObjectType = StaticType::New(scriptContext, TypeIds_Undefined, nullValue, ThrowErrorObject::DefaultEntryPoint);

mapType = DynamicType::New(scriptContext, TypeIds_Map, mapPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);

setType = DynamicType::New(scriptContext, TypeIds_Set, setPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);

weakMapType = DynamicType::New(scriptContext, TypeIds_WeakMap, weakMapPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);

weakSetType = DynamicType::New(scriptContext, TypeIds_WeakSet, weakSetPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);

TypePath *const iteratorResultPath = TypePath::New(recycler);
iteratorResultPath->Add(BuiltInPropertyRecords::value);
iteratorResultPath->Add(BuiltInPropertyRecords::done);
iteratorResultType = DynamicType::New(scriptContext, TypeIds_Object, objectPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, iteratorResultPath, iteratorResultPath->GetPathLength(), 2, sizeof(DynamicObject), true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, iteratorResultPath, iteratorResultPath->GetPathLength(), 2, sizeof(DynamicObject), true, true), true, true);

arrayIteratorType = DynamicType::New(scriptContext, TypeIds_ArrayIterator, arrayIteratorPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
mapIteratorType = DynamicType::New(scriptContext, TypeIds_MapIterator, mapIteratorPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
setIteratorType = DynamicType::New(scriptContext, TypeIds_SetIterator, setIteratorPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
stringIteratorType = DynamicType::New(scriptContext, TypeIds_StringIterator, stringIteratorPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
listIteratorType = DynamicType::New(scriptContext, TypeIds_ListIterator, iteratorPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);

if (config->IsES6GeneratorsEnabled())
{
Expand All @@ -711,10 +711,10 @@ namespace Js

#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
debugDisposableObjectType = DynamicType::New(scriptContext, TypeIds_Object, objectPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);

debugFuncExecutorInDisposeObjectType = DynamicType::New(scriptContext, TypeIds_Object, objectPrototype, nullptr,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
#endif
}

Expand Down Expand Up @@ -2711,8 +2711,8 @@ namespace Js
DeferredTypeHandler<InitializeRegexPrototype, DefaultDeferredTypeFilter, true>::GetDefaultInstance()));
}

SimplePathTypeHandler *typeHandler =
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true);
SimplePathTypeHandlerNoAttr *typeHandler =
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true);
// See JavascriptRegExp::IsWritable for property writability
if (!scriptConfig->IsES6RegExPrototypePropertiesEnabled())
{
Expand Down Expand Up @@ -6861,7 +6861,7 @@ namespace Js
}
oldCachedType = dynamicType;
#endif
SimplePathTypeHandler* typeHandler = SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, requestedInlineSlotCapacity, offsetOfInlineSlots, true, true);
SimplePathTypeHandlerNoAttr* typeHandler = SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, requestedInlineSlotCapacity, offsetOfInlineSlots, true, true);
dynamicType = DynamicType::New(scriptContext, typeId, prototype, RecyclableObject::DefaultEntryPoint, typeHandler, true, true);

if (useCache)
Expand Down Expand Up @@ -6891,7 +6891,7 @@ namespace Js
DynamicType* JavascriptLibrary::CreateObjectTypeNoCache(RecyclableObject* prototype, Js::TypeId typeId)
{
return DynamicType::New(scriptContext, typeId, prototype, RecyclableObject::DefaultEntryPoint,
SimplePathTypeHandler::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
SimplePathTypeHandlerNoAttr::New(scriptContext, this->GetRootPath(), 0, 0, 0, true, true), true, true);
}

DynamicType* JavascriptLibrary::CreateObjectType(RecyclableObject* prototype, uint16 requestedInlineSlotCapacity)
Expand Down
3 changes: 3 additions & 0 deletions lib/Runtime/Types/DynamicObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ namespace Js
friend class JavascriptNativeArray; // for xplat offsetof field access
friend class JavascriptOperators; // for ReplaceType
friend class PathTypeHandlerBase; // for ReplaceType
friend class SimplePathTypeHandlerNoAttr;
friend class SimplePathTypeHandlerWithAttr;
friend class PathTypeHandlerNoAttr;
friend class JavascriptLibrary; // for ReplaceType
friend class ScriptFunction; // for ReplaceType;
friend class JSON::JSONParser; //for ReplaceType
Expand Down
Loading

0 comments on commit e1b4272

Please sign in to comment.