| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/typer.h" | 5 #include "src/compiler/typer.h" |
| 6 | 6 |
| 7 #include <iomanip> | 7 #include <iomanip> |
| 8 | 8 |
| 9 #include "src/base/flags.h" | 9 #include "src/base/flags.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 static Type* ObjectIsString(Type*, Typer*); | 287 static Type* ObjectIsString(Type*, Typer*); |
| 288 static Type* ObjectIsUndetectable(Type*, Typer*); | 288 static Type* ObjectIsUndetectable(Type*, Typer*); |
| 289 | 289 |
| 290 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); | 290 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); |
| 291 | 291 |
| 292 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); | 292 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); |
| 293 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) | 293 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) |
| 294 #undef DECLARE_METHOD | 294 #undef DECLARE_METHOD |
| 295 | 295 |
| 296 static Type* JSTypeOfTyper(Type*, Typer*); | 296 static Type* JSTypeOfTyper(Type*, Typer*); |
| 297 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); | |
| 298 static Type* JSCallFunctionTyper(Type*, Typer*); | 297 static Type* JSCallFunctionTyper(Type*, Typer*); |
| 299 | 298 |
| 300 static Type* ReferenceEqualTyper(Type*, Type*, Typer*); | 299 static Type* ReferenceEqualTyper(Type*, Type*, Typer*); |
| 301 static Type* StringFromCharCodeTyper(Type*, Typer*); | 300 static Type* StringFromCharCodeTyper(Type*, Typer*); |
| 302 | 301 |
| 303 Reduction UpdateType(Node* node, Type* current) { | 302 Reduction UpdateType(Node* node, Type* current) { |
| 304 if (NodeProperties::IsTyped(node)) { | 303 if (NodeProperties::IsTyped(node)) { |
| 305 // Widen the type of a previously typed node. | 304 // Widen the type of a previously typed node. |
| 306 Type* previous = NodeProperties::GetType(node); | 305 Type* previous = NodeProperties::GetType(node); |
| 307 if (node->opcode() == IrOpcode::kPhi || | 306 if (node->opcode() == IrOpcode::kPhi || |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 } | 537 } |
| 539 | 538 |
| 540 | 539 |
| 541 // ----------------------------------------------------------------------------- | 540 // ----------------------------------------------------------------------------- |
| 542 | 541 |
| 543 | 542 |
| 544 // Control operators. | 543 // Control operators. |
| 545 | 544 |
| 546 Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); } | 545 Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); } |
| 547 | 546 |
| 548 Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); } | 547 Type* Typer::Visitor::TypeIfException(Node* node) { |
| 549 | 548 return Type::NonInternal(); |
| 549 } |
| 550 | 550 |
| 551 // Common operators. | 551 // Common operators. |
| 552 | 552 |
| 553 Type* Typer::Visitor::TypeParameter(Node* node) { return Type::Any(); } | 553 Type* Typer::Visitor::TypeParameter(Node* node) { return Type::Any(); } |
| 554 | 554 |
| 555 Type* Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); } | 555 Type* Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); } |
| 556 | 556 |
| 557 | 557 |
| 558 Type* Typer::Visitor::TypeInt32Constant(Node* node) { | 558 Type* Typer::Visitor::TypeInt32Constant(Node* node) { |
| 559 double number = OpParameter<int32_t>(node); | 559 double number = OpParameter<int32_t>(node); |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1073 Type* Typer::Visitor::TypeJSCreateLiteralObject(Node* node) { | 1073 Type* Typer::Visitor::TypeJSCreateLiteralObject(Node* node) { |
| 1074 return Type::OtherObject(); | 1074 return Type::OtherObject(); |
| 1075 } | 1075 } |
| 1076 | 1076 |
| 1077 | 1077 |
| 1078 Type* Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) { | 1078 Type* Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) { |
| 1079 return Type::OtherObject(); | 1079 return Type::OtherObject(); |
| 1080 } | 1080 } |
| 1081 | 1081 |
| 1082 | 1082 |
| 1083 Type* Typer::Visitor::JSLoadPropertyTyper(Type* object, Type* name, Typer* t) { | |
| 1084 // TODO(rossberg): Use range types and sized array types to filter undefined. | |
| 1085 if (object->IsArray() && name->Is(Type::Integral32())) { | |
| 1086 return Type::Union( | |
| 1087 object->AsArray()->Element(), Type::Undefined(), t->zone()); | |
| 1088 } | |
| 1089 return Type::Any(); | |
| 1090 } | |
| 1091 | |
| 1092 | |
| 1093 Type* Typer::Visitor::TypeJSLoadProperty(Node* node) { | 1083 Type* Typer::Visitor::TypeJSLoadProperty(Node* node) { |
| 1094 return TypeBinaryOp(node, JSLoadPropertyTyper); | 1084 return Type::NonInternal(); |
| 1095 } | 1085 } |
| 1096 | 1086 |
| 1097 | 1087 |
| 1098 Type* Typer::Visitor::TypeJSLoadNamed(Node* node) { | 1088 Type* Typer::Visitor::TypeJSLoadNamed(Node* node) { |
| 1099 return Type::Any(); | 1089 return Type::NonInternal(); |
| 1100 } | 1090 } |
| 1101 | 1091 |
| 1102 | 1092 Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) { |
| 1103 Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) { return Type::Any(); } | 1093 return Type::NonInternal(); |
| 1104 | 1094 } |
| 1105 | 1095 |
| 1106 // Returns a somewhat larger range if we previously assigned | 1096 // Returns a somewhat larger range if we previously assigned |
| 1107 // a (smaller) range to this node. This is used to speed up | 1097 // a (smaller) range to this node. This is used to speed up |
| 1108 // the fixpoint calculation in case there appears to be a loop | 1098 // the fixpoint calculation in case there appears to be a loop |
| 1109 // in the graph. In the current implementation, we are | 1099 // in the graph. In the current implementation, we are |
| 1110 // increasing the limits to the closest power of two. | 1100 // increasing the limits to the closest power of two. |
| 1111 Type* Typer::Visitor::Weaken(Node* node, Type* current_type, | 1101 Type* Typer::Visitor::Weaken(Node* node, Type* current_type, |
| 1112 Type* previous_type) { | 1102 Type* previous_type) { |
| 1113 static const double kWeakenMinLimits[] = { | 1103 static const double kWeakenMinLimits[] = { |
| 1114 0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0, | 1104 0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0, |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1352 case kGlobalEncodeURI: | 1342 case kGlobalEncodeURI: |
| 1353 case kGlobalEncodeURIComponent: | 1343 case kGlobalEncodeURIComponent: |
| 1354 case kGlobalEscape: | 1344 case kGlobalEscape: |
| 1355 case kGlobalUnescape: | 1345 case kGlobalUnescape: |
| 1356 return Type::String(); | 1346 return Type::String(); |
| 1357 default: | 1347 default: |
| 1358 break; | 1348 break; |
| 1359 } | 1349 } |
| 1360 } | 1350 } |
| 1361 } | 1351 } |
| 1362 return Type::Any(); | 1352 return Type::NonInternal(); |
| 1363 } | 1353 } |
| 1364 | 1354 |
| 1365 | 1355 |
| 1366 Type* Typer::Visitor::TypeJSCallFunction(Node* node) { | 1356 Type* Typer::Visitor::TypeJSCallFunction(Node* node) { |
| 1367 // TODO(bmeurer): We could infer better types if we wouldn't ignore the | 1357 // TODO(bmeurer): We could infer better types if we wouldn't ignore the |
| 1368 // argument types for the JSCallFunctionTyper above. | 1358 // argument types for the JSCallFunctionTyper above. |
| 1369 return TypeUnaryOp(node, JSCallFunctionTyper); | 1359 return TypeUnaryOp(node, JSCallFunctionTyper); |
| 1370 } | 1360 } |
| 1371 | 1361 |
| 1372 | 1362 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1395 return TypeUnaryOp(node, ToNumber); | 1385 return TypeUnaryOp(node, ToNumber); |
| 1396 case Runtime::kInlineToObject: | 1386 case Runtime::kInlineToObject: |
| 1397 return TypeUnaryOp(node, ToObject); | 1387 return TypeUnaryOp(node, ToObject); |
| 1398 case Runtime::kInlineToString: | 1388 case Runtime::kInlineToString: |
| 1399 return TypeUnaryOp(node, ToString); | 1389 return TypeUnaryOp(node, ToString); |
| 1400 case Runtime::kHasInPrototypeChain: | 1390 case Runtime::kHasInPrototypeChain: |
| 1401 return Type::Boolean(); | 1391 return Type::Boolean(); |
| 1402 default: | 1392 default: |
| 1403 break; | 1393 break; |
| 1404 } | 1394 } |
| 1395 // TODO(turbofan): This should be Type::NonInternal(), but unfortunately we |
| 1396 // have a few weird runtime calls that return the hole or even FixedArrays; |
| 1397 // change this once those weird runtime calls have been removed. |
| 1405 return Type::Any(); | 1398 return Type::Any(); |
| 1406 } | 1399 } |
| 1407 | 1400 |
| 1408 | 1401 |
| 1409 Type* Typer::Visitor::TypeJSConvertReceiver(Node* node) { | 1402 Type* Typer::Visitor::TypeJSConvertReceiver(Node* node) { |
| 1410 return Type::Receiver(); | 1403 return Type::Receiver(); |
| 1411 } | 1404 } |
| 1412 | 1405 |
| 1413 | 1406 |
| 1414 Type* Typer::Visitor::TypeJSForInNext(Node* node) { | 1407 Type* Typer::Visitor::TypeJSForInNext(Node* node) { |
| (...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2328 } | 2321 } |
| 2329 if (Type::IsInteger(*value)) { | 2322 if (Type::IsInteger(*value)) { |
| 2330 return Type::Range(value->Number(), value->Number(), zone()); | 2323 return Type::Range(value->Number(), value->Number(), zone()); |
| 2331 } | 2324 } |
| 2332 return Type::Constant(value, zone()); | 2325 return Type::Constant(value, zone()); |
| 2333 } | 2326 } |
| 2334 | 2327 |
| 2335 } // namespace compiler | 2328 } // namespace compiler |
| 2336 } // namespace internal | 2329 } // namespace internal |
| 2337 } // namespace v8 | 2330 } // namespace v8 |
| OLD | NEW |