Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart

Issue 23369004: Revert "Extract interceptor calls from raw is-checks." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 class SsaCodeGeneratorTask extends CompilerTask { 7 class SsaCodeGeneratorTask extends CompilerTask {
8 8
9 final JavaScriptBackend backend; 9 final JavaScriptBackend backend;
10 10
(...skipping 2198 matching lines...) Expand 10 before | Expand all | Expand 10 after
2209 2209
2210 List<js.Expression> arguments = <js.Expression>[object, record]; 2210 List<js.Expression> arguments = <js.Expression>[object, record];
2211 FunctionElement helper = 2211 FunctionElement helper =
2212 compiler.findHelper(const SourceString('isJsIndexable')); 2212 compiler.findHelper(const SourceString('isJsIndexable'));
2213 world.registerStaticUse(helper); 2213 world.registerStaticUse(helper);
2214 String helperName = backend.namer.isolateAccess(helper); 2214 String helperName = backend.namer.isolateAccess(helper);
2215 push(new js.Call(new js.VariableUse(helperName), arguments)); 2215 push(new js.Call(new js.VariableUse(helperName), arguments));
2216 if (negative) push(new js.Prefix('!', pop())); 2216 if (negative) push(new js.Prefix('!', pop()));
2217 } 2217 }
2218 2218
2219 void checkType(HInstruction input, HInstruction interceptor, 2219 void checkType(HInstruction input, DartType type, {bool negative: false}) {
2220 DartType type, {bool negative: false}) {
2221 Element element = type.element; 2220 Element element = type.element;
2222 if (element == backend.jsArrayClass) { 2221 if (element == backend.jsArrayClass) {
2223 checkArray(input, negative ? '!==': '==='); 2222 checkArray(input, negative ? '!==': '===');
2224 return; 2223 return;
2225 } else if (element == backend.jsMutableArrayClass) { 2224 } else if (element == backend.jsMutableArrayClass) {
2226 if (negative) { 2225 if (negative) {
2227 checkImmutableArray(input); 2226 checkImmutableArray(input);
2228 } else { 2227 } else {
2229 checkMutableArray(input); 2228 checkMutableArray(input);
2230 } 2229 }
2231 return; 2230 return;
2232 } else if (element == backend.jsExtendableArrayClass) { 2231 } else if (element == backend.jsExtendableArrayClass) {
2233 if (negative) { 2232 if (negative) {
2234 checkFixedArray(input); 2233 checkFixedArray(input);
2235 } else { 2234 } else {
2236 checkExtendableArray(input); 2235 checkExtendableArray(input);
2237 } 2236 }
2238 return; 2237 return;
2239 } else if (element == backend.jsFixedArrayClass) { 2238 } else if (element == backend.jsFixedArrayClass) {
2240 if (negative) { 2239 if (negative) {
2241 checkExtendableArray(input); 2240 checkExtendableArray(input);
2242 } else { 2241 } else {
2243 checkFixedArray(input); 2242 checkFixedArray(input);
2244 } 2243 }
2245 return; 2244 return;
2246 } 2245 }
2247 use(interceptor); 2246 use(input);
2248 2247
2248 // Hack in interceptor. Ideally the interceptor would occur at the
2249 // instruction level to allow optimizations, and checks would be broken into
2250 // several smaller tests.
2251 // This code is a slice of visitInterceptor for the univeral interceptor.
2252 String interceptorName = backend.namer.getInterceptorName(
2253 backend.getInterceptorMethod, backend.interceptedClasses);
2254 backend.registerSpecializedGetInterceptor(backend.interceptedClasses);
2255 backend.registerUseInterceptor(world);
2256
2257 var isolate = new js.VariableUse(backend.namer.CURRENT_ISOLATE);
2258 List<js.Expression> arguments = <js.Expression>[pop()];
2259 push(jsPropertyCall(isolate, interceptorName, arguments));
2249 world.registerIsCheck(type, work.resolutionTree); 2260 world.registerIsCheck(type, work.resolutionTree);
2250 2261
2251 js.PropertyAccess field = 2262 js.PropertyAccess field =
2252 new js.PropertyAccess.field(pop(), backend.namer.operatorIsType(type)); 2263 new js.PropertyAccess.field(pop(), backend.namer.operatorIsType(type));
2253 // We always negate at least once so that the result is boolified. 2264 // We always negate at least once so that the result is boolified.
2254 push(new js.Prefix('!', field)); 2265 push(new js.Prefix('!', field));
2255 // If the result is not negated, put another '!' in front. 2266 // If the result is not negated, put another '!' in front.
2256 if (!negative) push(new js.Prefix('!', pop())); 2267 if (!negative) push(new js.Prefix('!', pop()));
2257 } 2268 }
2258 2269
2259 void handleNumberOrStringSupertypeCheck(HInstruction input, 2270 void handleNumberOrStringSupertypeCheck(HInstruction input,
2260 HInstruction interceptor,
2261 DartType type, 2271 DartType type,
2262 { bool negative: false }) { 2272 { bool negative: false }) {
2263 assert(!identical(type.element, compiler.listClass) 2273 assert(!identical(type.element, compiler.listClass)
2264 && !Elements.isListSupertype(type.element, compiler) 2274 && !Elements.isListSupertype(type.element, compiler)
2265 && !Elements.isStringOnlySupertype(type.element, compiler)); 2275 && !Elements.isStringOnlySupertype(type.element, compiler));
2266 String relation = negative ? '!==' : '==='; 2276 String relation = negative ? '!==' : '===';
2267 checkNum(input, relation); 2277 checkNum(input, relation);
2268 js.Expression numberTest = pop(); 2278 js.Expression numberTest = pop();
2269 checkString(input, relation); 2279 checkString(input, relation);
2270 js.Expression stringTest = pop(); 2280 js.Expression stringTest = pop();
2271 checkObject(input, relation); 2281 checkObject(input, relation);
2272 js.Expression objectTest = pop(); 2282 js.Expression objectTest = pop();
2273 checkType(input, interceptor, type, negative: negative); 2283 checkType(input, type, negative: negative);
2274 String combiner = negative ? '&&' : '||'; 2284 String combiner = negative ? '&&' : '||';
2275 String combiner2 = negative ? '||' : '&&'; 2285 String combiner2 = negative ? '||' : '&&';
2276 push(new js.Binary(combiner, 2286 push(new js.Binary(combiner,
2277 new js.Binary(combiner, numberTest, stringTest), 2287 new js.Binary(combiner, numberTest, stringTest),
2278 new js.Binary(combiner2, objectTest, pop()))); 2288 new js.Binary(combiner2, objectTest, pop())));
2279 } 2289 }
2280 2290
2281 void handleStringSupertypeCheck(HInstruction input, 2291 void handleStringSupertypeCheck(HInstruction input,
2282 HInstruction interceptor,
2283 DartType type, 2292 DartType type,
2284 { bool negative: false }) { 2293 { bool negative: false }) {
2285 assert(!identical(type.element, compiler.listClass) 2294 assert(!identical(type.element, compiler.listClass)
2286 && !Elements.isListSupertype(type.element, compiler) 2295 && !Elements.isListSupertype(type.element, compiler)
2287 && !Elements.isNumberOrStringSupertype(type.element, compiler)); 2296 && !Elements.isNumberOrStringSupertype(type.element, compiler));
2288 String relation = negative ? '!==' : '==='; 2297 String relation = negative ? '!==' : '===';
2289 checkString(input, relation); 2298 checkString(input, relation);
2290 js.Expression stringTest = pop(); 2299 js.Expression stringTest = pop();
2291 checkObject(input, relation); 2300 checkObject(input, relation);
2292 js.Expression objectTest = pop(); 2301 js.Expression objectTest = pop();
2293 checkType(input, interceptor, type, negative: negative); 2302 checkType(input, type, negative: negative);
2294 String combiner = negative ? '||' : '&&'; 2303 String combiner = negative ? '||' : '&&';
2295 push(new js.Binary(negative ? '&&' : '||', 2304 push(new js.Binary(negative ? '&&' : '||',
2296 stringTest, 2305 stringTest,
2297 new js.Binary(combiner, objectTest, pop()))); 2306 new js.Binary(combiner, objectTest, pop())));
2298 } 2307 }
2299 2308
2300 void handleListOrSupertypeCheck(HInstruction input, 2309 void handleListOrSupertypeCheck(HInstruction input,
2301 HInstruction interceptor,
2302 DartType type, 2310 DartType type,
2303 { bool negative: false }) { 2311 { bool negative: false }) {
2304 assert(!identical(type.element, compiler.stringClass) 2312 assert(!identical(type.element, compiler.stringClass)
2305 && !Elements.isStringOnlySupertype(type.element, compiler) 2313 && !Elements.isStringOnlySupertype(type.element, compiler)
2306 && !Elements.isNumberOrStringSupertype(type.element, compiler)); 2314 && !Elements.isNumberOrStringSupertype(type.element, compiler));
2307 String relation = negative ? '!==' : '==='; 2315 String relation = negative ? '!==' : '===';
2308 checkObject(input, relation); 2316 checkObject(input, relation);
2309 js.Expression objectTest = pop(); 2317 js.Expression objectTest = pop();
2310 checkArray(input, relation); 2318 checkArray(input, relation);
2311 js.Expression arrayTest = pop(); 2319 js.Expression arrayTest = pop();
2312 checkType(input, interceptor, type, negative: negative); 2320 checkType(input, type, negative: negative);
2313 String combiner = negative ? '&&' : '||'; 2321 String combiner = negative ? '&&' : '||';
2314 push(new js.Binary(negative ? '||' : '&&', 2322 push(new js.Binary(negative ? '||' : '&&',
2315 objectTest, 2323 objectTest,
2316 new js.Binary(combiner, arrayTest, pop()))); 2324 new js.Binary(combiner, arrayTest, pop())));
2317 } 2325 }
2318 2326
2319 void visitIs(HIs node) { 2327 void visitIs(HIs node) {
2320 emitIs(node, "==="); 2328 emitIs(node, "===");
2321 } 2329 }
2322 2330
2323 void emitIs(HIs node, String relation) { 2331 void emitIs(HIs node, String relation) {
2324 DartType type = node.typeExpression; 2332 DartType type = node.typeExpression;
2325 world.registerIsCheck(type, work.resolutionTree); 2333 world.registerIsCheck(type, work.resolutionTree);
2326 HInstruction input = node.expression; 2334 HInstruction input = node.expression;
2327 2335
2328 // If this is changed to single == there are several places below that must 2336 // If this is changed to single == there are several places below that must
2329 // be changed to match. 2337 // be changed to match.
2330 assert(relation == '===' || relation == '!=='); 2338 assert(relation == '===' || relation == '!==');
2331 bool negative = relation == '!=='; 2339 bool negative = relation == '!==';
2332 2340
2333 if (node.isVariableCheck || node.isCompoundCheck) { 2341 if (node.isVariableCheck || node.isCompoundCheck) {
2334 use(node.checkCall); 2342 use(node.checkCall);
2335 if (negative) push(new js.Prefix('!', pop())); 2343 if (negative) push(new js.Prefix('!', pop()));
2336 } else { 2344 } else {
2337 assert(node.isRawCheck); 2345 assert(node.isRawCheck);
2338 HInstruction interceptor = node.interceptor;
2339 LibraryElement coreLibrary = compiler.coreLibrary; 2346 LibraryElement coreLibrary = compiler.coreLibrary;
2340 ClassElement objectClass = compiler.objectClass; 2347 ClassElement objectClass = compiler.objectClass;
2341 Element element = type.element; 2348 Element element = type.element;
2342 if (element == compiler.nullClass) { 2349 if (element == compiler.nullClass) {
2343 if (negative) { 2350 if (negative) {
2344 checkNonNull(input); 2351 checkNonNull(input);
2345 } else { 2352 } else {
2346 checkNull(input); 2353 checkNull(input);
2347 } 2354 }
2348 } else if (identical(element, objectClass) || type.treatAsDynamic) { 2355 } else if (identical(element, objectClass) || type.treatAsDynamic) {
(...skipping 14 matching lines...) Expand all
2363 attachLocationToLast(node); 2370 attachLocationToLast(node);
2364 } else if (element == compiler.intClass) { 2371 } else if (element == compiler.intClass) {
2365 // The is check in the code tells us that it might not be an 2372 // The is check in the code tells us that it might not be an
2366 // int. So we do a typeof first to avoid possible 2373 // int. So we do a typeof first to avoid possible
2367 // deoptimizations on the JS engine due to the Math.floor check. 2374 // deoptimizations on the JS engine due to the Math.floor check.
2368 checkNum(input, relation); 2375 checkNum(input, relation);
2369 js.Expression numTest = pop(); 2376 js.Expression numTest = pop();
2370 checkBigInt(input, relation); 2377 checkBigInt(input, relation);
2371 push(new js.Binary(negative ? '||' : '&&', numTest, pop()), node); 2378 push(new js.Binary(negative ? '||' : '&&', numTest, pop()), node);
2372 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { 2379 } else if (Elements.isNumberOrStringSupertype(element, compiler)) {
2373 handleNumberOrStringSupertypeCheck( 2380 handleNumberOrStringSupertypeCheck(input, type, negative: negative);
2374 input, interceptor, type, negative: negative);
2375 attachLocationToLast(node); 2381 attachLocationToLast(node);
2376 } else if (Elements.isStringOnlySupertype(element, compiler)) { 2382 } else if (Elements.isStringOnlySupertype(element, compiler)) {
2377 handleStringSupertypeCheck( 2383 handleStringSupertypeCheck(input, type, negative: negative);
2378 input, interceptor, type, negative: negative);
2379 attachLocationToLast(node); 2384 attachLocationToLast(node);
2380 } else if (identical(element, compiler.listClass) 2385 } else if (identical(element, compiler.listClass)
2381 || Elements.isListSupertype(element, compiler)) { 2386 || Elements.isListSupertype(element, compiler)) {
2382 handleListOrSupertypeCheck( 2387 handleListOrSupertypeCheck(input, type, negative: negative);
2383 input, interceptor, type, negative: negative);
2384 attachLocationToLast(node); 2388 attachLocationToLast(node);
2385 } else if (type.kind == TypeKind.FUNCTION) { 2389 } else if (element.isTypedef()) {
2386 checkType(input, interceptor, type, negative: negative); 2390 if (negative) {
2391 checkNull(input);
2392 } else {
2393 checkNonNull(input);
2394 }
2395 js.Expression nullTest = pop();
2396 checkType(input, type, negative: negative);
2397 push(new js.Binary(negative ? '||' : '&&', nullTest, pop()));
2387 attachLocationToLast(node); 2398 attachLocationToLast(node);
2388 } else if ((input.canBePrimitive(compiler) 2399 } else if ((input.canBePrimitive(compiler)
2389 && !input.canBePrimitiveArray(compiler)) 2400 && !input.canBePrimitiveArray(compiler))
2390 || input.canBeNull()) { 2401 || input.canBeNull()) {
2391 checkObject(input, relation); 2402 checkObject(input, relation);
2392 js.Expression objectTest = pop(); 2403 js.Expression objectTest = pop();
2393 checkType(input, interceptor, type, negative: negative); 2404 checkType(input, type, negative: negative);
2394 push(new js.Binary(negative ? '||' : '&&', objectTest, pop()), node); 2405 push(new js.Binary(negative ? '||' : '&&', objectTest, pop()), node);
2395 } else { 2406 } else {
2396 checkType(input, interceptor, type, negative: negative); 2407 checkType(input, type, negative: negative);
2397 attachLocationToLast(node); 2408 attachLocationToLast(node);
2398 } 2409 }
2399 } 2410 }
2411 if (node.nullOk) {
2412 if (negative) {
2413 checkNonNull(input);
2414 push(new js.Binary('&&', pop(), pop()), node);
2415 } else {
2416 checkNull(input);
2417 push(new js.Binary('||', pop(), pop()), node);
2418 }
2419 }
2400 } 2420 }
2401 2421
2402 js.Expression generateTest(HCheck node) { 2422 js.Expression generateTest(HCheck node) {
2403 HInstruction input = node.checkedInput; 2423 HInstruction input = node.checkedInput;
2404 TypeMask receiver = input.instructionType.computeMask(compiler); 2424 TypeMask receiver = input.instructionType.computeMask(compiler);
2405 TypeMask mask = node.instructionType.computeMask(compiler); 2425 TypeMask mask = node.instructionType.computeMask(compiler);
2406 bool turnIntoNullCheck = mask.nullable() == receiver; 2426 bool turnIntoNullCheck = mask.nullable() == receiver;
2407 js.Expression test; 2427 js.Expression test;
2408 if (turnIntoNullCheck) { 2428 if (turnIntoNullCheck) {
2409 use(input); 2429 use(input);
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
2969 if (leftType.canBeNull() && rightType.canBeNull()) { 2989 if (leftType.canBeNull() && rightType.canBeNull()) {
2970 if (left.isConstantNull() || right.isConstantNull() || 2990 if (left.isConstantNull() || right.isConstantNull() ||
2971 (leftType.isPrimitive(compiler) && leftType == rightType)) { 2991 (leftType.isPrimitive(compiler) && leftType == rightType)) {
2972 return '=='; 2992 return '==';
2973 } 2993 }
2974 return null; 2994 return null;
2975 } else { 2995 } else {
2976 return '==='; 2996 return '===';
2977 } 2997 }
2978 } 2998 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/builder.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698