[dart2js] new-rti: experiment - fault in '$is' test

Change-Id: Ie6d17e3439fb67fe79e9dec4dc7cb5437d1f6915
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121766
Reviewed-by: Stephen Adams <sra@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
This commit is contained in:
Stephen Adams 2019-11-08 06:00:06 +00:00 committed by commit-bot@chromium.org
parent 7a45228584
commit b334ea8320
3 changed files with 90 additions and 8 deletions

View file

@ -2571,6 +2571,8 @@ abstract class ModularNamer {
return asName(fixedNames.deferredAction);
case JsGetName.OPERATOR_AS_PREFIX:
return asName(fixedNames.operatorAsPrefix);
case JsGetName.OPERATOR_IS_PREFIX:
return asName(fixedNames.operatorIsPrefix);
case JsGetName.SIGNATURE_NAME:
return asName(fixedNames.operatorSignature);
case JsGetName.RTI_NAME:

View file

@ -109,6 +109,18 @@ class Rti {
rti._precomputed1 = precomputed;
}
// Data value used by some tests.
@pragma('dart2js:noElision')
Object _specializedTestResource;
static Object _getSpecializedTestResource(Rti rti) {
return rti._specializedTestResource;
}
static void _setSpecializedTestResource(Rti rti, Object value) {
rti._specializedTestResource = value;
}
// The Type object corresponding to this Rti.
Object _cachedRuntimeType;
static _Type _getCachedRuntimeType(Rti rti) =>
@ -549,6 +561,9 @@ _FunctionParameters _instantiateFunctionParameters(universe,
return result;
}
bool _isDartObject(object) => _Utils.instanceOf(object,
JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartObjectConstructor));
bool _isClosure(object) => _Utils.instanceOf(object,
JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartClosureConstructor));
@ -597,10 +612,7 @@ Rti instanceType(object) {
// called, similar to a one-shot interceptor call. This would improve type
// lookup in ListMixin code as the interceptor is JavaScript 'this'.
if (_Utils.instanceOf(
object,
JS_BUILTIN(
'depends:none;effects:none;', JsBuiltin.dartObjectConstructor))) {
if (_isDartObject(object)) {
return _instanceType(object);
}
@ -762,6 +774,16 @@ bool _installSpecializedIsTest(object) {
isFn = RAW_DART_FUNCTION_REF(_isString);
} else if (JS_GET_NAME(JsGetName.BOOL_RECIPE) == key) {
isFn = RAW_DART_FUNCTION_REF(_isBool);
} else {
String name = Rti._getInterfaceName(testRti);
var arguments = Rti._getInterfaceTypeArguments(testRti);
if (JS(
'bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) {
String propertyName =
'${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}';
Rti._setSpecializedTestResource(testRti, propertyName);
isFn = RAW_DART_FUNCTION_REF(_isTestViaProperty);
}
}
}
@ -778,6 +800,24 @@ bool _generalIsTestImplementation(object) {
return isSubtype(_theUniverse(), objectRti, testRti);
}
/// Called from generated code.
bool _isTestViaProperty(object) {
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
var tag = Rti._getSpecializedTestResource(testRti);
// This test is redundant with getInterceptor below, but getInterceptor does
// the tests in the wrong order for most tags, so it is usually faster to have
// this check.
if (_isDartObject(object)) {
return JS('bool', '!!#[#]', object, tag);
}
var interceptor = getInterceptor(object);
return JS('bool', '!!#[#]', interceptor, tag);
}
/// Called from generated code.
_generalAsCheckImplementation(object) {
if (object == null) return object;

View file

@ -111,6 +111,18 @@ class Rti {
rti._precomputed1 = precomputed;
}
// Data value used by some tests.
@pragma('dart2js:noElision')
Object _specializedTestResource;
static Object _getSpecializedTestResource(Rti rti) {
return rti._specializedTestResource;
}
static void _setSpecializedTestResource(Rti rti, Object value) {
rti._specializedTestResource = value;
}
// The Type object corresponding to this Rti.
Object _cachedRuntimeType;
static _Type _getCachedRuntimeType(Rti rti) =>
@ -551,6 +563,9 @@ _FunctionParameters _instantiateFunctionParameters(universe,
return result;
}
bool _isDartObject(object) => _Utils.instanceOf(object,
JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartObjectConstructor));
bool _isClosure(object) => _Utils.instanceOf(object,
JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartClosureConstructor));
@ -599,10 +614,7 @@ Rti instanceType(object) {
// called, similar to a one-shot interceptor call. This would improve type
// lookup in ListMixin code as the interceptor is JavaScript 'this'.
if (_Utils.instanceOf(
object,
JS_BUILTIN(
'depends:none;effects:none;', JsBuiltin.dartObjectConstructor))) {
if (_isDartObject(object)) {
return _instanceType(object);
}
@ -764,6 +776,16 @@ bool _installSpecializedIsTest(object) {
isFn = RAW_DART_FUNCTION_REF(_isString);
} else if (JS_GET_NAME(JsGetName.BOOL_RECIPE) == key) {
isFn = RAW_DART_FUNCTION_REF(_isBool);
} else {
String name = Rti._getInterfaceName(testRti);
var arguments = Rti._getInterfaceTypeArguments(testRti);
if (JS(
'bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) {
String propertyName =
'${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}';
Rti._setSpecializedTestResource(testRti, propertyName);
isFn = RAW_DART_FUNCTION_REF(_isTestViaProperty);
}
}
}
@ -780,6 +802,24 @@ bool _generalIsTestImplementation(object) {
return isSubtype(_theUniverse(), objectRti, testRti);
}
/// Called from generated code.
bool _isTestViaProperty(object) {
// This static method is installed on an Rti object as a JavaScript instance
// method. The Rti object is 'this'.
Rti testRti = _castToRti(JS('', 'this'));
var tag = Rti._getSpecializedTestResource(testRti);
// This test is redundant with getInterceptor below, but getInterceptor does
// the tests in the wrong order for most tags, so it is usually faster to have
// this check.
if (_isDartObject(object)) {
return JS('bool', '!!#[#]', object, tag);
}
var interceptor = getInterceptor(object);
return JS('bool', '!!#[#]', interceptor, tag);
}
/// Called from generated code.
_generalAsCheckImplementation(object) {
if (object == null) return object;