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 |