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" |
7 #include "src/compilation-dependencies.h" | 8 #include "src/compilation-dependencies.h" |
8 #include "src/compiler/access-builder.h" | 9 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/node-matchers.h" | 11 #include "src/compiler/node-matchers.h" |
11 #include "src/compiler/node-properties.h" | 12 #include "src/compiler/node-properties.h" |
12 #include "src/compiler/simplified-operator.h" | 13 #include "src/compiler/simplified-operator.h" |
13 #include "src/compiler/type-cache.h" | 14 #include "src/compiler/type-cache.h" |
14 #include "src/compiler/types.h" | 15 #include "src/compiler/types.h" |
15 #include "src/objects-inl.h" | 16 #include "src/objects-inl.h" |
16 | 17 |
(...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1478 r.InputsMatchTwo(type_cache_.kSafeInteger, type_cache_.kTenOrUndefined)) { | 1479 r.InputsMatchTwo(type_cache_.kSafeInteger, type_cache_.kTenOrUndefined)) { |
1479 // Number.parseInt(a:safe-integer) -> a | 1480 // Number.parseInt(a:safe-integer) -> a |
1480 // Number.parseInt(a:safe-integer,b:#0\/undefined) -> a | 1481 // Number.parseInt(a:safe-integer,b:#0\/undefined) -> a |
1481 // Number.parseInt(a:safe-integer,b:#10\/undefined) -> a | 1482 // Number.parseInt(a:safe-integer,b:#10\/undefined) -> a |
1482 Node* value = r.GetJSCallInput(0); | 1483 Node* value = r.GetJSCallInput(0); |
1483 return Replace(value); | 1484 return Replace(value); |
1484 } | 1485 } |
1485 return NoChange(); | 1486 return NoChange(); |
1486 } | 1487 } |
1487 | 1488 |
| 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 Node* undefined = jsgraph()->UndefinedConstant(); |
| 1544 effect = graph()->NewNode( |
| 1545 simplified()->StoreField(AccessBuilder::ForDictionaryMaxNumberKey()), |
| 1546 value, undefined, effect, control); |
| 1547 effect = graph()->NewNode( |
| 1548 simplified()->StoreField( |
| 1549 AccessBuilder::ForDictionaryNextEnumerationIndex()), |
| 1550 value, jsgraph()->SmiConstant(PropertyDetails::kInitialIndex), effect, |
| 1551 control); |
| 1552 // Initialize hte Properties fields. |
| 1553 for (int index = NameDictionary::kNextEnumerationIndexIndex + 1; |
| 1554 index < length; index++) { |
| 1555 effect = graph()->NewNode( |
| 1556 simplified()->StoreField( |
| 1557 AccessBuilder::ForFixedArraySlot(index, kNoWriteBarrier)), |
| 1558 value, undefined, effect, control); |
| 1559 } |
| 1560 properties = effect = |
| 1561 graph()->NewNode(common()->FinishRegion(), value, effect); |
| 1562 } |
| 1563 |
| 1564 int const instance_size = instance_map->instance_size(); |
| 1565 if (instance_size > kMaxRegularHeapObjectSize) return NoChange(); |
| 1566 dependencies()->AssumeInitialMapCantChange(instance_map); |
| 1567 |
| 1568 // Emit code to allocate the JSObject instance for the given |
| 1569 // {instance_map}. |
| 1570 effect = graph()->NewNode( |
| 1571 common()->BeginRegion(RegionObservability::kNotObservable), effect); |
| 1572 Node* value = effect = |
| 1573 graph()->NewNode(simplified()->Allocate(NOT_TENURED), |
| 1574 jsgraph()->Constant(instance_size), effect, control); |
| 1575 effect = |
| 1576 graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), value, |
| 1577 jsgraph()->HeapConstant(instance_map), effect, control); |
| 1578 effect = graph()->NewNode( |
| 1579 simplified()->StoreField(AccessBuilder::ForJSObjectProperties()), value, |
| 1580 properties, effect, control); |
| 1581 effect = graph()->NewNode( |
| 1582 simplified()->StoreField(AccessBuilder::ForJSObjectElements()), value, |
| 1583 jsgraph()->EmptyFixedArrayConstant(), effect, control); |
| 1584 // Initialize Object fields. |
| 1585 Node* undefined = jsgraph()->UndefinedConstant(); |
| 1586 for (int offset = JSObject::kHeaderSize; offset < instance_size; |
| 1587 offset += kPointerSize) { |
| 1588 effect = graph()->NewNode( |
| 1589 simplified()->StoreField( |
| 1590 AccessBuilder::ForJSObjectOffset(offset, kNoWriteBarrier)), |
| 1591 value, undefined, effect, control); |
| 1592 } |
| 1593 value = effect = graph()->NewNode(common()->FinishRegion(), value, effect); |
| 1594 |
| 1595 // replace it |
| 1596 ReplaceWithValue(node, value, effect, control); |
| 1597 return Replace(value); |
| 1598 } |
| 1599 |
1488 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits ) | 1600 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits ) |
1489 Reduction JSBuiltinReducer::ReduceStringFromCharCode(Node* node) { | 1601 Reduction JSBuiltinReducer::ReduceStringFromCharCode(Node* node) { |
1490 JSCallReduction r(node); | 1602 JSCallReduction r(node); |
1491 if (r.InputsMatchOne(Type::PlainPrimitive())) { | 1603 if (r.InputsMatchOne(Type::PlainPrimitive())) { |
1492 // String.fromCharCode(a:plain-primitive) -> StringFromCharCode(a) | 1604 // String.fromCharCode(a:plain-primitive) -> StringFromCharCode(a) |
1493 Node* input = ToNumber(r.GetJSCallInput(0)); | 1605 Node* input = ToNumber(r.GetJSCallInput(0)); |
1494 Node* value = graph()->NewNode(simplified()->StringFromCharCode(), input); | 1606 Node* value = graph()->NewNode(simplified()->StringFromCharCode(), input); |
1495 return Replace(value); | 1607 return Replace(value); |
1496 } | 1608 } |
1497 return NoChange(); | 1609 return NoChange(); |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1983 break; | 2095 break; |
1984 case kNumberIsNaN: | 2096 case kNumberIsNaN: |
1985 reduction = ReduceNumberIsNaN(node); | 2097 reduction = ReduceNumberIsNaN(node); |
1986 break; | 2098 break; |
1987 case kNumberIsSafeInteger: | 2099 case kNumberIsSafeInteger: |
1988 reduction = ReduceNumberIsSafeInteger(node); | 2100 reduction = ReduceNumberIsSafeInteger(node); |
1989 break; | 2101 break; |
1990 case kNumberParseInt: | 2102 case kNumberParseInt: |
1991 reduction = ReduceNumberParseInt(node); | 2103 reduction = ReduceNumberParseInt(node); |
1992 break; | 2104 break; |
| 2105 case kObjectCreate: |
| 2106 reduction = ReduceObjectCreate(node); |
| 2107 break; |
1993 case kStringFromCharCode: | 2108 case kStringFromCharCode: |
1994 reduction = ReduceStringFromCharCode(node); | 2109 reduction = ReduceStringFromCharCode(node); |
1995 break; | 2110 break; |
1996 case kStringCharAt: | 2111 case kStringCharAt: |
1997 return ReduceStringCharAt(node); | 2112 return ReduceStringCharAt(node); |
1998 case kStringCharCodeAt: | 2113 case kStringCharCodeAt: |
1999 return ReduceStringCharCodeAt(node); | 2114 return ReduceStringCharCodeAt(node); |
2000 case kStringIterator: | 2115 case kStringIterator: |
2001 return ReduceStringIterator(node); | 2116 return ReduceStringIterator(node); |
2002 case kStringIteratorNext: | 2117 case kStringIteratorNext: |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2066 return jsgraph()->simplified(); | 2181 return jsgraph()->simplified(); |
2067 } | 2182 } |
2068 | 2183 |
2069 JSOperatorBuilder* JSBuiltinReducer::javascript() const { | 2184 JSOperatorBuilder* JSBuiltinReducer::javascript() const { |
2070 return jsgraph()->javascript(); | 2185 return jsgraph()->javascript(); |
2071 } | 2186 } |
2072 | 2187 |
2073 } // namespace compiler | 2188 } // namespace compiler |
2074 } // namespace internal | 2189 } // namespace internal |
2075 } // namespace v8 | 2190 } // namespace v8 |
OLD | NEW |