| 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/js-builtin-reducer.h" | 5 #include "src/compiler/js-builtin-reducer.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | |
| 8 #include "src/compilation-dependencies.h" | 7 #include "src/compilation-dependencies.h" |
| 9 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
| 10 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 11 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| 12 #include "src/compiler/node-properties.h" | 11 #include "src/compiler/node-properties.h" |
| 13 #include "src/compiler/simplified-operator.h" | 12 #include "src/compiler/simplified-operator.h" |
| 14 #include "src/compiler/type-cache.h" | 13 #include "src/compiler/type-cache.h" |
| 15 #include "src/compiler/types.h" | 14 #include "src/compiler/types.h" |
| 16 #include "src/objects-inl.h" | 15 #include "src/objects-inl.h" |
| 17 | 16 |
| (...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 r.InputsMatchTwo(type_cache_.kSafeInteger, type_cache_.kTenOrUndefined)) { | 1478 r.InputsMatchTwo(type_cache_.kSafeInteger, type_cache_.kTenOrUndefined)) { |
| 1480 // Number.parseInt(a:safe-integer) -> a | 1479 // Number.parseInt(a:safe-integer) -> a |
| 1481 // Number.parseInt(a:safe-integer,b:#0\/undefined) -> a | 1480 // Number.parseInt(a:safe-integer,b:#0\/undefined) -> a |
| 1482 // Number.parseInt(a:safe-integer,b:#10\/undefined) -> a | 1481 // Number.parseInt(a:safe-integer,b:#10\/undefined) -> a |
| 1483 Node* value = r.GetJSCallInput(0); | 1482 Node* value = r.GetJSCallInput(0); |
| 1484 return Replace(value); | 1483 return Replace(value); |
| 1485 } | 1484 } |
| 1486 return NoChange(); | 1485 return NoChange(); |
| 1487 } | 1486 } |
| 1488 | 1487 |
| 1489 // ES6 section #sec-object.create Object.create(proto, properties) | |
| 1490 Reduction JSBuiltinReducer::ReduceObjectCreate(Node* node) { | |
| 1491 // We need exactly target, receiver and value parameters. | |
| 1492 int arg_count = node->op()->ValueInputCount(); | |
| 1493 if (arg_count != 3) return NoChange(); | |
| 1494 Node* effect = NodeProperties::GetEffectInput(node); | |
| 1495 Node* control = NodeProperties::GetControlInput(node); | |
| 1496 Node* prototype = NodeProperties::GetValueInput(node, 2); | |
| 1497 Type* prototype_type = NodeProperties::GetType(prototype); | |
| 1498 Handle<Map> instance_map; | |
| 1499 if (!prototype_type->IsHeapConstant()) return NoChange(); | |
| 1500 Handle<HeapObject> prototype_const = | |
| 1501 prototype_type->AsHeapConstant()->Value(); | |
| 1502 if (!prototype_const->IsNull(isolate()) && !prototype_const->IsJSReceiver()) { | |
| 1503 return NoChange(); | |
| 1504 } | |
| 1505 instance_map = Map::GetObjectCreateMap(prototype_const); | |
| 1506 Node* properties = jsgraph()->EmptyFixedArrayConstant(); | |
| 1507 if (instance_map->is_dictionary_map()) { | |
| 1508 // Allocated an empty NameDictionary as backing store for the properties. | |
| 1509 Handle<Map> map(isolate()->heap()->hash_table_map(), isolate()); | |
| 1510 int capacity = | |
| 1511 NameDictionary::ComputeCapacity(NameDictionary::kInitialCapacity); | |
| 1512 DCHECK(base::bits::IsPowerOfTwo32(capacity)); | |
| 1513 int length = NameDictionary::EntryToIndex(capacity); | |
| 1514 int size = NameDictionary::SizeFor(length); | |
| 1515 | |
| 1516 effect = graph()->NewNode( | |
| 1517 common()->BeginRegion(RegionObservability::kNotObservable), effect); | |
| 1518 | |
| 1519 Node* value = effect = | |
| 1520 graph()->NewNode(simplified()->Allocate(NOT_TENURED), | |
| 1521 jsgraph()->Constant(size), effect, control); | |
| 1522 effect = | |
| 1523 graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), | |
| 1524 value, jsgraph()->HeapConstant(map), effect, control); | |
| 1525 | |
| 1526 // Initialize FixedArray fields. | |
| 1527 effect = graph()->NewNode( | |
| 1528 simplified()->StoreField(AccessBuilder::ForFixedArrayLength()), value, | |
| 1529 jsgraph()->SmiConstant(length), effect, control); | |
| 1530 // Initialize HashTable fields. | |
| 1531 effect = | |
| 1532 graph()->NewNode(simplified()->StoreField( | |
| 1533 AccessBuilder::ForHashTableBaseNumberOfElements()), | |
| 1534 value, jsgraph()->SmiConstant(0), effect, control); | |
| 1535 effect = graph()->NewNode( | |
| 1536 simplified()->StoreField( | |
| 1537 AccessBuilder::ForHashTableBaseNumberOfDeletedElement()), | |
| 1538 value, jsgraph()->SmiConstant(0), effect, control); | |
| 1539 effect = graph()->NewNode( | |
| 1540 simplified()->StoreField(AccessBuilder::ForHashTableBaseCapacity()), | |
| 1541 value, jsgraph()->SmiConstant(capacity), effect, control); | |
| 1542 // Initialize Dictionary fields. | |
| 1543 effect = graph()->NewNode( | |
| 1544 simplified()->StoreField(AccessBuilder::ForDictionaryMaxNumberKey()), | |
| 1545 value, jsgraph()->UndefinedConstant(), effect, control); | |
| 1546 effect = graph()->NewNode( | |
| 1547 simplified()->StoreField(AccessBuilder::ForNextEnumerationIndex()), | |
| 1548 value, jsgraph()->SmiConstant(PropertyDetails::kInitialIndex), effect, | |
| 1549 control); | |
| 1550 | |
| 1551 properties = effect = | |
| 1552 graph()->NewNode(common()->FinishRegion(), value, effect); | |
| 1553 } | |
| 1554 | |
| 1555 int const instance_size = instance_map->instance_size(); | |
| 1556 dependencies()->AssumeInitialMapCantChange(instance_map); | |
| 1557 | |
| 1558 // Emit code to allocate the JSObject instance for the given | |
| 1559 // {instance_map}. | |
| 1560 effect = graph()->NewNode( | |
| 1561 common()->BeginRegion(RegionObservability::kNotObservable), effect); | |
| 1562 Node* value = effect = | |
| 1563 graph()->NewNode(simplified()->Allocate(NOT_TENURED), | |
| 1564 jsgraph()->Constant(instance_size), effect, control); | |
| 1565 effect = | |
| 1566 graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), value, | |
| 1567 jsgraph()->HeapConstant(instance_map), effect, control); | |
| 1568 effect = graph()->NewNode( | |
| 1569 simplified()->StoreField(AccessBuilder::ForJSObjectProperties()), value, | |
| 1570 properties, effect, control); | |
| 1571 effect = graph()->NewNode( | |
| 1572 simplified()->StoreField(AccessBuilder::ForJSObjectElements()), value, | |
| 1573 jsgraph()->EmptyFixedArrayConstant(), effect, control); | |
| 1574 | |
| 1575 value = effect = graph()->NewNode(common()->FinishRegion(), value, effect); | |
| 1576 | |
| 1577 // replace it | |
| 1578 ReplaceWithValue(node, value, effect, control); | |
| 1579 return Replace(value); | |
| 1580 } | |
| 1581 | |
| 1582 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits ) | 1488 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits ) |
| 1583 Reduction JSBuiltinReducer::ReduceStringFromCharCode(Node* node) { | 1489 Reduction JSBuiltinReducer::ReduceStringFromCharCode(Node* node) { |
| 1584 JSCallReduction r(node); | 1490 JSCallReduction r(node); |
| 1585 if (r.InputsMatchOne(Type::PlainPrimitive())) { | 1491 if (r.InputsMatchOne(Type::PlainPrimitive())) { |
| 1586 // String.fromCharCode(a:plain-primitive) -> StringFromCharCode(a) | 1492 // String.fromCharCode(a:plain-primitive) -> StringFromCharCode(a) |
| 1587 Node* input = ToNumber(r.GetJSCallInput(0)); | 1493 Node* input = ToNumber(r.GetJSCallInput(0)); |
| 1588 Node* value = graph()->NewNode(simplified()->StringFromCharCode(), input); | 1494 Node* value = graph()->NewNode(simplified()->StringFromCharCode(), input); |
| 1589 return Replace(value); | 1495 return Replace(value); |
| 1590 } | 1496 } |
| 1591 return NoChange(); | 1497 return NoChange(); |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2077 break; | 1983 break; |
| 2078 case kNumberIsNaN: | 1984 case kNumberIsNaN: |
| 2079 reduction = ReduceNumberIsNaN(node); | 1985 reduction = ReduceNumberIsNaN(node); |
| 2080 break; | 1986 break; |
| 2081 case kNumberIsSafeInteger: | 1987 case kNumberIsSafeInteger: |
| 2082 reduction = ReduceNumberIsSafeInteger(node); | 1988 reduction = ReduceNumberIsSafeInteger(node); |
| 2083 break; | 1989 break; |
| 2084 case kNumberParseInt: | 1990 case kNumberParseInt: |
| 2085 reduction = ReduceNumberParseInt(node); | 1991 reduction = ReduceNumberParseInt(node); |
| 2086 break; | 1992 break; |
| 2087 case kObjectCreate: | |
| 2088 reduction = ReduceObjectCreate(node); | |
| 2089 break; | |
| 2090 case kStringFromCharCode: | 1993 case kStringFromCharCode: |
| 2091 reduction = ReduceStringFromCharCode(node); | 1994 reduction = ReduceStringFromCharCode(node); |
| 2092 break; | 1995 break; |
| 2093 case kStringCharAt: | 1996 case kStringCharAt: |
| 2094 return ReduceStringCharAt(node); | 1997 return ReduceStringCharAt(node); |
| 2095 case kStringCharCodeAt: | 1998 case kStringCharCodeAt: |
| 2096 return ReduceStringCharCodeAt(node); | 1999 return ReduceStringCharCodeAt(node); |
| 2097 case kStringIterator: | 2000 case kStringIterator: |
| 2098 return ReduceStringIterator(node); | 2001 return ReduceStringIterator(node); |
| 2099 case kStringIteratorNext: | 2002 case kStringIteratorNext: |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 return jsgraph()->simplified(); | 2066 return jsgraph()->simplified(); |
| 2164 } | 2067 } |
| 2165 | 2068 |
| 2166 JSOperatorBuilder* JSBuiltinReducer::javascript() const { | 2069 JSOperatorBuilder* JSBuiltinReducer::javascript() const { |
| 2167 return jsgraph()->javascript(); | 2070 return jsgraph()->javascript(); |
| 2168 } | 2071 } |
| 2169 | 2072 |
| 2170 } // namespace compiler | 2073 } // namespace compiler |
| 2171 } // namespace internal | 2074 } // namespace internal |
| 2172 } // namespace v8 | 2075 } // namespace v8 |
| OLD | NEW |