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

Side by Side Diff: src/hydrogen.cc

Issue 141363005: A64: Synchronize with r15204. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 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
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 merge_block_(NULL) { 704 merge_block_(NULL) {
705 continuation->Continue(&first_true_block_, 705 continuation->Continue(&first_true_block_,
706 &first_false_block_, 706 &first_false_block_,
707 &position_); 707 &position_);
708 } 708 }
709 709
710 710
711 HInstruction* HGraphBuilder::IfBuilder::IfCompare( 711 HInstruction* HGraphBuilder::IfBuilder::IfCompare(
712 HValue* left, 712 HValue* left,
713 HValue* right, 713 HValue* right,
714 Token::Value token, 714 Token::Value token) {
715 Representation input_representation) {
716 HCompareIDAndBranch* compare = 715 HCompareIDAndBranch* compare =
717 new(zone()) HCompareIDAndBranch(left, right, token); 716 new(zone()) HCompareIDAndBranch(left, right, token);
718 compare->set_observed_input_representation(input_representation,
719 input_representation);
720 compare->AssumeRepresentation(input_representation);
721 AddCompare(compare); 717 AddCompare(compare);
722 return compare; 718 return compare;
723 } 719 }
724 720
725 721
726 HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left, 722 HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left,
727 Handle<Map> map) { 723 Handle<Map> map) {
728 HCompareMap* compare = 724 HCompareMap* compare =
729 new(zone()) HCompareMap(left, map, first_true_block_, first_false_block_); 725 new(zone()) HCompareMap(left, map, first_true_block_, first_false_block_);
730 AddCompare(compare); 726 AddCompare(compare);
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 builder_->set_current_block(exit_block_); 958 builder_->set_current_block(exit_block_);
963 // Pop the phi from the expression stack 959 // Pop the phi from the expression stack
964 builder_->environment()->Pop(); 960 builder_->environment()->Pop();
965 finished_ = true; 961 finished_ = true;
966 } 962 }
967 963
968 964
969 HGraph* HGraphBuilder::CreateGraph() { 965 HGraph* HGraphBuilder::CreateGraph() {
970 graph_ = new(zone()) HGraph(info_); 966 graph_ = new(zone()) HGraph(info_);
971 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); 967 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_);
972 HPhase phase("H_Block building", isolate()); 968 HPhase phase("H_Block building", isolate(), zone());
973 set_current_block(graph()->entry_block()); 969 set_current_block(graph()->entry_block());
974 if (!BuildGraph()) return NULL; 970 if (!BuildGraph()) return NULL;
975 graph()->FinalizeUniqueValueIds(); 971 graph()->FinalizeUniqueValueIds();
976 return graph_; 972 return graph_;
977 } 973 }
978 974
979 975
980 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 976 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
981 ASSERT(current_block() != NULL); 977 ASSERT(current_block() != NULL);
982 current_block()->AddInstruction(instr); 978 current_block()->AddInstruction(instr);
(...skipping 16 matching lines...) Expand all
999 HBoundsCheck* result = new(graph()->zone()) HBoundsCheck(index, length); 995 HBoundsCheck* result = new(graph()->zone()) HBoundsCheck(index, length);
1000 AddInstruction(result); 996 AddInstruction(result);
1001 return result; 997 return result;
1002 } 998 }
1003 999
1004 1000
1005 HReturn* HGraphBuilder::AddReturn(HValue* value) { 1001 HReturn* HGraphBuilder::AddReturn(HValue* value) {
1006 HValue* context = environment()->LookupContext(); 1002 HValue* context = environment()->LookupContext();
1007 int num_parameters = graph()->info()->num_parameters(); 1003 int num_parameters = graph()->info()->num_parameters();
1008 HValue* params = AddInstruction(new(graph()->zone()) 1004 HValue* params = AddInstruction(new(graph()->zone())
1009 HConstant(num_parameters, Representation::Integer32())); 1005 HConstant(num_parameters));
1010 HReturn* return_instruction = new(graph()->zone()) 1006 HReturn* return_instruction = new(graph()->zone())
1011 HReturn(value, context, params); 1007 HReturn(value, context, params);
1012 current_block()->FinishExit(return_instruction); 1008 current_block()->FinishExit(return_instruction);
1013 return return_instruction; 1009 return return_instruction;
1014 } 1010 }
1015 1011
1016 1012
1017 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 1013 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
1018 HBasicBlock* b = graph()->CreateBasicBlock(); 1014 HBasicBlock* b = graph()->CreateBasicBlock();
1019 b->SetInitialEnvironment(env); 1015 b->SetInitialEnvironment(env);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 1160
1165 environment()->Push(new_elements); 1161 environment()->Push(new_elements);
1166 capacity_checker.Else(); 1162 capacity_checker.Else();
1167 1163
1168 environment()->Push(elements); 1164 environment()->Push(elements);
1169 capacity_checker.End(); 1165 capacity_checker.End();
1170 1166
1171 if (is_js_array) { 1167 if (is_js_array) {
1172 HValue* new_length = AddInstruction( 1168 HValue* new_length = AddInstruction(
1173 HAdd::New(zone, context, length, graph_->GetConstant1())); 1169 HAdd::New(zone, context, length, graph_->GetConstant1()));
1174 new_length->AssumeRepresentation(Representation::Integer32());
1175 new_length->ClearFlag(HValue::kCanOverflow); 1170 new_length->ClearFlag(HValue::kCanOverflow);
1176 1171
1177 Representation representation = IsFastElementsKind(kind) 1172 Representation representation = IsFastElementsKind(kind)
1178 ? Representation::Smi() : Representation::Tagged(); 1173 ? Representation::Smi() : Representation::Tagged();
1179 AddStore(object, HObjectAccess::ForArrayLength(), new_length, 1174 AddStore(object, HObjectAccess::ForArrayLength(), new_length,
1180 representation); 1175 representation);
1181 } 1176 }
1182 1177
1183 length_checker.Else(); 1178 length_checker.Else();
1184 1179
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 } 1332 }
1338 1333
1339 1334
1340 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, 1335 HValue* HGraphBuilder::BuildAllocateElements(HValue* context,
1341 ElementsKind kind, 1336 ElementsKind kind,
1342 HValue* capacity) { 1337 HValue* capacity) {
1343 Zone* zone = this->zone(); 1338 Zone* zone = this->zone();
1344 1339
1345 int elements_size = IsFastDoubleElementsKind(kind) 1340 int elements_size = IsFastDoubleElementsKind(kind)
1346 ? kDoubleSize : kPointerSize; 1341 ? kDoubleSize : kPointerSize;
1347 HConstant* elements_size_value = 1342 HConstant* elements_size_value = new(zone) HConstant(elements_size);
1348 new(zone) HConstant(elements_size, Representation::Integer32());
1349 AddInstruction(elements_size_value); 1343 AddInstruction(elements_size_value);
1350 HValue* mul = AddInstruction( 1344 HValue* mul = AddInstruction(
1351 HMul::New(zone, context, capacity, elements_size_value)); 1345 HMul::New(zone, context, capacity, elements_size_value));
1352 mul->AssumeRepresentation(Representation::Integer32());
1353 mul->ClearFlag(HValue::kCanOverflow); 1346 mul->ClearFlag(HValue::kCanOverflow);
1354 1347
1355 HConstant* header_size = 1348 HConstant* header_size = new(zone) HConstant(FixedArray::kHeaderSize);
1356 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32());
1357 AddInstruction(header_size); 1349 AddInstruction(header_size);
1358 HValue* total_size = AddInstruction( 1350 HValue* total_size = AddInstruction(
1359 HAdd::New(zone, context, mul, header_size)); 1351 HAdd::New(zone, context, mul, header_size));
1360 total_size->AssumeRepresentation(Representation::Integer32());
1361 total_size->ClearFlag(HValue::kCanOverflow); 1352 total_size->ClearFlag(HValue::kCanOverflow);
1362 1353
1363 HAllocate::Flags flags = HAllocate::DefaultFlags(kind); 1354 HAllocate::Flags flags = HAllocate::DefaultFlags(kind);
1364 if (isolate()->heap()->ShouldGloballyPretenure()) { 1355 if (isolate()->heap()->ShouldGloballyPretenure()) {
1365 // TODO(hpayer): When pretenuring can be internalized, flags can become 1356 // TODO(hpayer): When pretenuring can be internalized, flags can become
1366 // private to HAllocate. 1357 // private to HAllocate.
1367 if (IsFastDoubleElementsKind(kind)) { 1358 if (IsFastDoubleElementsKind(kind)) {
1368 flags = static_cast<HAllocate::Flags>( 1359 flags = static_cast<HAllocate::Flags>(
1369 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); 1360 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE);
1370 } else { 1361 } else {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 1399
1409 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, 1400 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
1410 HValue* array_map, 1401 HValue* array_map,
1411 AllocationSiteMode mode, 1402 AllocationSiteMode mode,
1412 HValue* allocation_site_payload, 1403 HValue* allocation_site_payload,
1413 HValue* length_field) { 1404 HValue* length_field) {
1414 1405
1415 AddStore(array, HObjectAccess::ForMap(), array_map); 1406 AddStore(array, HObjectAccess::ForMap(), array_map);
1416 1407
1417 HConstant* empty_fixed_array = 1408 HConstant* empty_fixed_array =
1418 new(zone()) HConstant( 1409 new(zone()) HConstant(isolate()->factory()->empty_fixed_array());
1419 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()),
1420 Representation::Tagged());
1421 AddInstruction(empty_fixed_array); 1410 AddInstruction(empty_fixed_array);
1422 1411
1423 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 1412 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
1424 AddStore(array, access, empty_fixed_array); 1413 AddStore(array, access, empty_fixed_array);
1425 AddStore(array, HObjectAccess::ForArrayLength(), length_field); 1414 AddStore(array, HObjectAccess::ForArrayLength(), length_field);
1426 1415
1427 if (mode == TRACK_ALLOCATION_SITE) { 1416 if (mode == TRACK_ALLOCATION_SITE) {
1428 BuildCreateAllocationSiteInfo(array, 1417 BuildCreateAllocationSiteInfo(array,
1429 JSArray::kSize, 1418 JSArray::kSize,
1430 allocation_site_payload); 1419 allocation_site_payload);
(...skipping 18 matching lines...) Expand all
1449 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); 1438 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck);
1450 } 1439 }
1451 1440
1452 1441
1453 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, 1442 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context,
1454 HValue* old_capacity) { 1443 HValue* old_capacity) {
1455 Zone* zone = this->zone(); 1444 Zone* zone = this->zone();
1456 HValue* half_old_capacity = 1445 HValue* half_old_capacity =
1457 AddInstruction(HShr::New(zone, context, old_capacity, 1446 AddInstruction(HShr::New(zone, context, old_capacity,
1458 graph_->GetConstant1())); 1447 graph_->GetConstant1()));
1459 half_old_capacity->AssumeRepresentation(Representation::Integer32());
1460 half_old_capacity->ClearFlag(HValue::kCanOverflow); 1448 half_old_capacity->ClearFlag(HValue::kCanOverflow);
1461 1449
1462 HValue* new_capacity = AddInstruction( 1450 HValue* new_capacity = AddInstruction(
1463 HAdd::New(zone, context, half_old_capacity, old_capacity)); 1451 HAdd::New(zone, context, half_old_capacity, old_capacity));
1464 new_capacity->AssumeRepresentation(Representation::Integer32());
1465 new_capacity->ClearFlag(HValue::kCanOverflow); 1452 new_capacity->ClearFlag(HValue::kCanOverflow);
1466 1453
1467 HValue* min_growth = 1454 HValue* min_growth = AddInstruction(new(zone) HConstant(16));
1468 AddInstruction(new(zone) HConstant(16, Representation::Integer32()));
1469 1455
1470 new_capacity = AddInstruction( 1456 new_capacity = AddInstruction(
1471 HAdd::New(zone, context, new_capacity, min_growth)); 1457 HAdd::New(zone, context, new_capacity, min_growth));
1472 new_capacity->AssumeRepresentation(Representation::Integer32());
1473 new_capacity->ClearFlag(HValue::kCanOverflow); 1458 new_capacity->ClearFlag(HValue::kCanOverflow);
1474 1459
1475 return new_capacity; 1460 return new_capacity;
1476 } 1461 }
1477 1462
1478 1463
1479 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { 1464 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) {
1480 Zone* zone = this->zone(); 1465 Zone* zone = this->zone();
1481 Heap* heap = isolate()->heap(); 1466 Heap* heap = isolate()->heap();
1482 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize 1467 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 ElementsKind elements_kind, 1503 ElementsKind elements_kind,
1519 HValue* from, 1504 HValue* from,
1520 HValue* to) { 1505 HValue* to) {
1521 // Fast elements kinds need to be initialized in case statements below cause 1506 // Fast elements kinds need to be initialized in case statements below cause
1522 // a garbage collection. 1507 // a garbage collection.
1523 Factory* factory = isolate()->factory(); 1508 Factory* factory = isolate()->factory();
1524 1509
1525 double nan_double = FixedDoubleArray::hole_nan_as_double(); 1510 double nan_double = FixedDoubleArray::hole_nan_as_double();
1526 Zone* zone = this->zone(); 1511 Zone* zone = this->zone();
1527 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) 1512 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
1528 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), 1513 ? AddInstruction(new(zone) HConstant(factory->the_hole_value()))
1529 Representation::Tagged())) 1514 : AddInstruction(new(zone) HConstant(nan_double));
1530 : AddInstruction(new(zone) HConstant(nan_double,
1531 Representation::Double()));
1532 1515
1533 // Special loop unfolding case 1516 // Special loop unfolding case
1534 static const int kLoopUnfoldLimit = 4; 1517 static const int kLoopUnfoldLimit = 4;
1535 bool unfold_loop = false; 1518 bool unfold_loop = false;
1536 int initial_capacity = JSArray::kPreallocatedArrayElements; 1519 int initial_capacity = JSArray::kPreallocatedArrayElements;
1537 if (from->IsConstant() && to->IsConstant() && 1520 if (from->IsConstant() && to->IsConstant() &&
1538 initial_capacity <= kLoopUnfoldLimit) { 1521 initial_capacity <= kLoopUnfoldLimit) {
1539 HConstant* constant_from = HConstant::cast(from); 1522 HConstant* constant_from = HConstant::cast(from);
1540 HConstant* constant_to = HConstant::cast(to); 1523 HConstant* constant_to = HConstant::cast(to);
1541 1524
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 int elems_offset = size; 1617 int elems_offset = size;
1635 if (length > 0) { 1618 if (length > 0) {
1636 size += IsFastDoubleElementsKind(kind) 1619 size += IsFastDoubleElementsKind(kind)
1637 ? FixedDoubleArray::SizeFor(length) 1620 ? FixedDoubleArray::SizeFor(length)
1638 : FixedArray::SizeFor(length); 1621 : FixedArray::SizeFor(length);
1639 } 1622 }
1640 1623
1641 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); 1624 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind);
1642 // Allocate both the JS array and the elements array in one big 1625 // Allocate both the JS array and the elements array in one big
1643 // allocation. This avoids multiple limit checks. 1626 // allocation. This avoids multiple limit checks.
1644 HValue* size_in_bytes = 1627 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(size));
1645 AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
1646 HInstruction* object = 1628 HInstruction* object =
1647 AddInstruction(new(zone) HAllocate(context, 1629 AddInstruction(new(zone) HAllocate(context,
1648 size_in_bytes, 1630 size_in_bytes,
1649 HType::JSObject(), 1631 HType::JSObject(),
1650 allocate_flags)); 1632 allocate_flags));
1651 1633
1652 // Copy the JS array part. 1634 // Copy the JS array part.
1653 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { 1635 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
1654 if ((i != JSArray::kElementsOffset) || (length == 0)) { 1636 if ((i != JSArray::kElementsOffset) || (length == 0)) {
1655 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); 1637 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 kind)); 1675 kind));
1694 } 1676 }
1695 } 1677 }
1696 1678
1697 return object; 1679 return object;
1698 } 1680 }
1699 1681
1700 1682
1701 void HGraphBuilder::BuildCompareNil( 1683 void HGraphBuilder::BuildCompareNil(
1702 HValue* value, 1684 HValue* value,
1703 CompareNilICStub::Types types, 1685 Handle<Type> type,
1704 Handle<Map> map,
1705 int position, 1686 int position,
1706 HIfContinuation* continuation) { 1687 HIfContinuation* continuation) {
1707 IfBuilder if_nil(this, position); 1688 IfBuilder if_nil(this, position);
1708 bool needs_or = false; 1689 bool needs_or = false;
1709 if (types.Contains(CompareNilICStub::NULL_TYPE)) { 1690 if (type->Maybe(Type::Null())) {
1710 if (needs_or) if_nil.Or(); 1691 if (needs_or) if_nil.Or();
1711 if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull()); 1692 if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull());
1712 needs_or = true; 1693 needs_or = true;
1713 } 1694 }
1714 if (types.Contains(CompareNilICStub::UNDEFINED)) { 1695 if (type->Maybe(Type::Undefined())) {
1715 if (needs_or) if_nil.Or(); 1696 if (needs_or) if_nil.Or();
1716 if_nil.If<HCompareObjectEqAndBranch>(value, 1697 if_nil.If<HCompareObjectEqAndBranch>(value,
1717 graph()->GetConstantUndefined()); 1698 graph()->GetConstantUndefined());
1718 needs_or = true; 1699 needs_or = true;
1719 } 1700 }
1720 // Handle either undetectable or monomorphic, not both. 1701 if (type->Maybe(Type::Undetectable())) {
1721 ASSERT(!types.Contains(CompareNilICStub::UNDETECTABLE) ||
1722 !types.Contains(CompareNilICStub::MONOMORPHIC_MAP));
1723 if (types.Contains(CompareNilICStub::UNDETECTABLE)) {
1724 if (needs_or) if_nil.Or(); 1702 if (needs_or) if_nil.Or();
1725 if_nil.If<HIsUndetectableAndBranch>(value); 1703 if_nil.If<HIsUndetectableAndBranch>(value);
1726 } else { 1704 } else {
1727 if_nil.Then(); 1705 if_nil.Then();
1728 if_nil.Else(); 1706 if_nil.Else();
1729 if (!map.is_null() && types.Contains(CompareNilICStub::MONOMORPHIC_MAP)) { 1707 if (type->NumClasses() == 1) {
1730 BuildCheckNonSmi(value); 1708 BuildCheckNonSmi(value);
1731 // For ICs, the map checked below is a sentinel map that gets replaced by 1709 // For ICs, the map checked below is a sentinel map that gets replaced by
1732 // the monomorphic map when the code is used as a template to generate a 1710 // the monomorphic map when the code is used as a template to generate a
1733 // new IC. For optimized functions, there is no sentinel map, the map 1711 // new IC. For optimized functions, there is no sentinel map, the map
1734 // emitted below is the actual monomorphic map. 1712 // emitted below is the actual monomorphic map.
1735 BuildCheckMap(value, map); 1713 BuildCheckMap(value, type->Classes().Current());
1736 } else { 1714 } else {
1737 if_nil.Deopt(); 1715 if_nil.Deopt();
1738 } 1716 }
1739 } 1717 }
1740 1718
1741 if_nil.CaptureContinuation(continuation); 1719 if_nil.CaptureContinuation(continuation);
1742 } 1720 }
1743 1721
1744 1722
1745 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, 1723 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object,
(...skipping 16 matching lines...) Expand all
1762 HGlobalObject(context)); 1740 HGlobalObject(context));
1763 HObjectAccess access = HObjectAccess::ForJSObjectOffset( 1741 HObjectAccess access = HObjectAccess::ForJSObjectOffset(
1764 GlobalObject::kNativeContextOffset); 1742 GlobalObject::kNativeContextOffset);
1765 return AddLoad(global_object, access); 1743 return AddLoad(global_object, access);
1766 } 1744 }
1767 1745
1768 1746
1769 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) { 1747 HInstruction* HGraphBuilder::BuildGetArrayFunction(HValue* context) {
1770 HInstruction* native_context = BuildGetNativeContext(context); 1748 HInstruction* native_context = BuildGetNativeContext(context);
1771 HInstruction* index = AddInstruction(new(zone()) 1749 HInstruction* index = AddInstruction(new(zone())
1772 HConstant(Context::ARRAY_FUNCTION_INDEX, Representation::Integer32())); 1750 HConstant(Context::ARRAY_FUNCTION_INDEX));
1773 1751
1774 return AddInstruction(new (zone()) 1752 return AddInstruction(new (zone())
1775 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS)); 1753 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS));
1776 } 1754 }
1777 1755
1778 1756
1779 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 1757 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
1780 ElementsKind kind, 1758 ElementsKind kind,
1781 HValue* allocation_site_payload, 1759 HValue* allocation_site_payload,
1782 bool disable_allocation_sites) : 1760 bool disable_allocation_sites) :
(...skipping 15 matching lines...) Expand all
1798 mode_(DONT_TRACK_ALLOCATION_SITE), 1776 mode_(DONT_TRACK_ALLOCATION_SITE),
1799 allocation_site_payload_(NULL), 1777 allocation_site_payload_(NULL),
1800 constructor_function_(constructor_function) { 1778 constructor_function_(constructor_function) {
1801 } 1779 }
1802 1780
1803 1781
1804 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { 1782 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
1805 HInstruction* native_context = builder()->BuildGetNativeContext(context); 1783 HInstruction* native_context = builder()->BuildGetNativeContext(context);
1806 1784
1807 HInstruction* index = builder()->AddInstruction(new(zone()) 1785 HInstruction* index = builder()->AddInstruction(new(zone())
1808 HConstant(Context::JS_ARRAY_MAPS_INDEX, Representation::Integer32())); 1786 HConstant(Context::JS_ARRAY_MAPS_INDEX));
1809 1787
1810 HInstruction* map_array = builder()->AddInstruction(new(zone()) 1788 HInstruction* map_array = builder()->AddInstruction(new(zone())
1811 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS)); 1789 HLoadKeyed(native_context, index, NULL, FAST_ELEMENTS));
1812 1790
1813 HInstruction* kind_index = builder()->AddInstruction(new(zone()) 1791 HInstruction* kind_index = builder()->AddInstruction(new(zone())
1814 HConstant(kind_, Representation::Integer32())); 1792 HConstant(kind_));
1815 1793
1816 return builder()->AddInstruction(new(zone()) 1794 return builder()->AddInstruction(new(zone())
1817 HLoadKeyed(map_array, kind_index, NULL, FAST_ELEMENTS)); 1795 HLoadKeyed(map_array, kind_index, NULL, FAST_ELEMENTS));
1818 } 1796 }
1819 1797
1820 1798
1821 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 1799 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
1822 // Find the map near the constructor function 1800 // Find the map near the constructor function
1823 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1801 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1824 return AddInstruction( 1802 return AddInstruction(
(...skipping 12 matching lines...) Expand all
1837 if (mode_ == TRACK_ALLOCATION_SITE) { 1815 if (mode_ == TRACK_ALLOCATION_SITE) {
1838 base_size += AllocationSiteInfo::kSize; 1816 base_size += AllocationSiteInfo::kSize;
1839 } 1817 }
1840 1818
1841 if (IsFastDoubleElementsKind(kind_)) { 1819 if (IsFastDoubleElementsKind(kind_)) {
1842 base_size += FixedDoubleArray::kHeaderSize; 1820 base_size += FixedDoubleArray::kHeaderSize;
1843 } else { 1821 } else {
1844 base_size += FixedArray::kHeaderSize; 1822 base_size += FixedArray::kHeaderSize;
1845 } 1823 }
1846 1824
1847 HInstruction* elements_size_value = new(zone()) 1825 HInstruction* elements_size_value = new(zone()) HConstant(elements_size());
1848 HConstant(elements_size(), Representation::Integer32());
1849 AddInstruction(elements_size_value); 1826 AddInstruction(elements_size_value);
1850 HInstruction* mul = HMul::New(zone(), context, length_node, 1827 HInstruction* mul = HMul::New(zone(), context, length_node,
1851 elements_size_value); 1828 elements_size_value);
1852 mul->AssumeRepresentation(Representation::Integer32());
1853 mul->ClearFlag(HValue::kCanOverflow); 1829 mul->ClearFlag(HValue::kCanOverflow);
1854 AddInstruction(mul); 1830 AddInstruction(mul);
1855 1831
1856 HInstruction* base = new(zone()) HConstant(base_size, 1832 HInstruction* base = new(zone()) HConstant(base_size);
1857 Representation::Integer32());
1858 AddInstruction(base); 1833 AddInstruction(base);
1859 HInstruction* total_size = HAdd::New(zone(), context, base, mul); 1834 HInstruction* total_size = HAdd::New(zone(), context, base, mul);
1860 total_size->AssumeRepresentation(Representation::Integer32());
1861 total_size->ClearFlag(HValue::kCanOverflow); 1835 total_size->ClearFlag(HValue::kCanOverflow);
1862 AddInstruction(total_size); 1836 AddInstruction(total_size);
1863 return total_size; 1837 return total_size;
1864 } 1838 }
1865 1839
1866 1840
1867 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { 1841 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
1868 int base_size = JSArray::kSize; 1842 int base_size = JSArray::kSize;
1869 if (mode_ == TRACK_ALLOCATION_SITE) { 1843 if (mode_ == TRACK_ALLOCATION_SITE) {
1870 base_size += AllocationSiteInfo::kSize; 1844 base_size += AllocationSiteInfo::kSize;
1871 } 1845 }
1872 1846
1873 base_size += IsFastDoubleElementsKind(kind_) 1847 base_size += IsFastDoubleElementsKind(kind_)
1874 ? FixedDoubleArray::SizeFor(initial_capacity()) 1848 ? FixedDoubleArray::SizeFor(initial_capacity())
1875 : FixedArray::SizeFor(initial_capacity()); 1849 : FixedArray::SizeFor(initial_capacity());
1876 1850
1877 HConstant* array_size = 1851 HConstant* array_size = new(zone()) HConstant(base_size);
1878 new(zone()) HConstant(base_size, Representation::Integer32());
1879 AddInstruction(array_size); 1852 AddInstruction(array_size);
1880 return array_size; 1853 return array_size;
1881 } 1854 }
1882 1855
1883 1856
1884 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { 1857 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
1885 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); 1858 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
1886 HConstant* capacity = 1859 HConstant* capacity = new(zone()) HConstant(initial_capacity());
1887 new(zone()) HConstant(initial_capacity(), Representation::Integer32());
1888 AddInstruction(capacity); 1860 AddInstruction(capacity);
1889 return AllocateArray(size_in_bytes, 1861 return AllocateArray(size_in_bytes,
1890 capacity, 1862 capacity,
1891 builder()->graph()->GetConstant0(), 1863 builder()->graph()->GetConstant0(),
1892 true); 1864 true);
1893 } 1865 }
1894 1866
1895 1867
1896 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, 1868 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity,
1897 HValue* length_field, 1869 HValue* length_field,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1955 Representation representation) { 1927 Representation representation) {
1956 HLoadNamedField *instr = 1928 HLoadNamedField *instr =
1957 new(zone()) HLoadNamedField(object, access, typecheck, representation); 1929 new(zone()) HLoadNamedField(object, access, typecheck, representation);
1958 AddInstruction(instr); 1930 AddInstruction(instr);
1959 return instr; 1931 return instr;
1960 } 1932 }
1961 1933
1962 1934
1963 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, 1935 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
1964 Handle<Map> map) { 1936 Handle<Map> map) {
1965 HValue* constant = 1937 HValue* constant = AddInstruction(new(zone()) HConstant(map));
1966 AddInstruction(new(zone()) HConstant(map, Representation::Tagged()));
1967 HStoreNamedField *instr = 1938 HStoreNamedField *instr =
1968 new(zone()) HStoreNamedField(object, HObjectAccess::ForMap(), constant); 1939 new(zone()) HStoreNamedField(object, HObjectAccess::ForMap(), constant);
1969 AddInstruction(instr); 1940 AddInstruction(instr);
1970 return instr; 1941 return instr;
1971 } 1942 }
1972 1943
1973 1944
1974 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) 1945 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info)
1975 : HGraphBuilder(info), 1946 : HGraphBuilder(info),
1976 function_state_(NULL), 1947 function_state_(NULL),
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
2408 HLoopInformation* loop_; 2379 HLoopInformation* loop_;
2409 HBasicBlock* block_; 2380 HBasicBlock* block_;
2410 HBasicBlock* loop_header_; 2381 HBasicBlock* loop_header_;
2411 int loop_index; 2382 int loop_index;
2412 int loop_length; 2383 int loop_length;
2413 HSuccessorIterator successor_iterator; 2384 HSuccessorIterator successor_iterator;
2414 }; 2385 };
2415 2386
2416 2387
2417 void HGraph::OrderBlocks() { 2388 void HGraph::OrderBlocks() {
2418 HPhase phase("H_Block ordering", isolate()); 2389 HPhase phase("H_Block ordering", isolate(), zone());
2419 BitVector visited(blocks_.length(), zone()); 2390 BitVector visited(blocks_.length(), zone());
2420 2391
2421 ZoneList<HBasicBlock*> reverse_result(8, zone()); 2392 ZoneList<HBasicBlock*> reverse_result(8, zone());
2422 HBasicBlock* start = blocks_[0]; 2393 HBasicBlock* start = blocks_[0];
2423 PostorderProcessor* postorder = 2394 PostorderProcessor* postorder =
2424 PostorderProcessor::CreateEntryProcessor(zone(), start, &visited); 2395 PostorderProcessor::CreateEntryProcessor(zone(), start, &visited);
2425 while (postorder != NULL) { 2396 while (postorder != NULL) {
2426 postorder = postorder->PerformStep(zone(), &visited, &reverse_result); 2397 postorder = postorder->PerformStep(zone(), &visited, &reverse_result);
2427 } 2398 }
2428 blocks_.Rewind(0); 2399 blocks_.Rewind(0);
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
3009 // (Before each HEnterInlined, there is a non-foldable HSimulate 2980 // (Before each HEnterInlined, there is a non-foldable HSimulate
3010 // anyway, so we get the barrier in the other direction for free.) 2981 // anyway, so we get the barrier in the other direction for free.)
3011 // Simply remove all accumulated simulates without merging. This 2982 // Simply remove all accumulated simulates without merging. This
3012 // is safe because simulates after instructions with side effects 2983 // is safe because simulates after instructions with side effects
3013 // are never added to the merge list. 2984 // are never added to the merge list.
3014 while (!mergelist.is_empty()) { 2985 while (!mergelist.is_empty()) {
3015 mergelist.RemoveLast()->DeleteAndReplaceWith(NULL); 2986 mergelist.RemoveLast()->DeleteAndReplaceWith(NULL);
3016 } 2987 }
3017 continue; 2988 continue;
3018 } 2989 }
2990 if (current->IsReturn()) {
2991 // Drop mergeable simulates in the list. This is safe because
2992 // simulates after instructions with side effects are never added
2993 // to the merge list.
2994 while (!mergelist.is_empty()) {
2995 mergelist.RemoveLast()->DeleteAndReplaceWith(NULL);
2996 }
2997 continue;
2998 }
3019 // Skip the non-simulates and the first simulate. 2999 // Skip the non-simulates and the first simulate.
3020 if (!current->IsSimulate()) continue; 3000 if (!current->IsSimulate()) continue;
3021 if (first) { 3001 if (first) {
3022 first = false; 3002 first = false;
3023 continue; 3003 continue;
3024 } 3004 }
3025 HSimulate* current_simulate = HSimulate::cast(current); 3005 HSimulate* current_simulate = HSimulate::cast(current);
3026 if ((current_simulate->previous()->HasObservableSideEffects() && 3006 if ((current_simulate->previous()->HasObservableSideEffects() &&
3027 !current_simulate->next()->IsSimulate()) || 3007 !current_simulate->next()->IsSimulate()) ||
3028 !current_simulate->is_candidate_for_removal()) { 3008 !current_simulate->is_candidate_for_removal()) {
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
3545 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, 3525 FunctionState::FunctionState(HOptimizedGraphBuilder* owner,
3546 CompilationInfo* info, 3526 CompilationInfo* info,
3547 InliningKind inlining_kind) 3527 InliningKind inlining_kind)
3548 : owner_(owner), 3528 : owner_(owner),
3549 compilation_info_(info), 3529 compilation_info_(info),
3550 call_context_(NULL), 3530 call_context_(NULL),
3551 inlining_kind_(inlining_kind), 3531 inlining_kind_(inlining_kind),
3552 function_return_(NULL), 3532 function_return_(NULL),
3553 test_context_(NULL), 3533 test_context_(NULL),
3554 entry_(NULL), 3534 entry_(NULL),
3535 arguments_object_(NULL),
3555 arguments_elements_(NULL), 3536 arguments_elements_(NULL),
3556 outer_(owner->function_state()) { 3537 outer_(owner->function_state()) {
3557 if (outer_ != NULL) { 3538 if (outer_ != NULL) {
3558 // State for an inline function. 3539 // State for an inline function.
3559 if (owner->ast_context()->IsTest()) { 3540 if (owner->ast_context()->IsTest()) {
3560 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); 3541 HBasicBlock* if_true = owner->graph()->CreateBasicBlock();
3561 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); 3542 HBasicBlock* if_false = owner->graph()->CreateBasicBlock();
3562 if_true->MarkAsInlineReturnTarget(owner->current_block()); 3543 if_true->MarkAsInlineReturnTarget(owner->current_block());
3563 if_false->MarkAsInlineReturnTarget(owner->current_block()); 3544 if_false->MarkAsInlineReturnTarget(owner->current_block());
3564 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); 3545 TestContext* outer_test_context = TestContext::cast(owner->ast_context());
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
3817 } while (false) 3798 } while (false)
3818 3799
3819 3800
3820 #define CHECK_ALIVE(call) \ 3801 #define CHECK_ALIVE(call) \
3821 do { \ 3802 do { \
3822 call; \ 3803 call; \
3823 if (HasStackOverflow() || current_block() == NULL) return; \ 3804 if (HasStackOverflow() || current_block() == NULL) return; \
3824 } while (false) 3805 } while (false)
3825 3806
3826 3807
3808 #define CHECK_ALIVE_OR_RETURN(call, value) \
3809 do { \
3810 call; \
3811 if (HasStackOverflow() || current_block() == NULL) return value; \
3812 } while (false)
3813
3814
3827 void HOptimizedGraphBuilder::Bailout(const char* reason) { 3815 void HOptimizedGraphBuilder::Bailout(const char* reason) {
3828 current_info()->set_bailout_reason(reason); 3816 current_info()->set_bailout_reason(reason);
3829 SetStackOverflow(); 3817 SetStackOverflow();
3830 } 3818 }
3831 3819
3832 3820
3833 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { 3821 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) {
3834 EffectContext for_effect(this); 3822 EffectContext for_effect(this);
3835 Visit(expr); 3823 Visit(expr);
3836 } 3824 }
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after
4692 4680
4693 while (!arguments.is_empty()) { 4681 while (!arguments.is_empty()) {
4694 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); 4682 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast()));
4695 } 4683 }
4696 return call; 4684 return call;
4697 } 4685 }
4698 4686
4699 4687
4700 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { 4688 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) {
4701 HConstant* undefined_constant = new(zone()) HConstant( 4689 HConstant* undefined_constant = new(zone()) HConstant(
4702 isolate()->factory()->undefined_value(), Representation::Tagged()); 4690 isolate()->factory()->undefined_value());
4703 AddInstruction(undefined_constant); 4691 AddInstruction(undefined_constant);
4704 graph()->set_undefined_constant(undefined_constant); 4692 graph()->set_undefined_constant(undefined_constant);
4705 4693
4706 HArgumentsObject* object = new(zone()) HArgumentsObject; 4694 // Create an arguments object containing the initial parameters. Set the
4707 AddInstruction(object); 4695 // initial values of parameters including "this" having parameter index 0.
4708 graph()->SetArgumentsObject(object);
4709
4710 // Set the initial values of parameters including "this". "This" has
4711 // parameter index 0.
4712 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); 4696 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count());
4713 4697 HArgumentsObject* arguments_object =
4698 new(zone()) HArgumentsObject(environment()->parameter_count(), zone());
4714 for (int i = 0; i < environment()->parameter_count(); ++i) { 4699 for (int i = 0; i < environment()->parameter_count(); ++i) {
4715 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i)); 4700 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i));
4701 arguments_object->AddArgument(parameter, zone());
4716 environment()->Bind(i, parameter); 4702 environment()->Bind(i, parameter);
4717 } 4703 }
4704 AddInstruction(arguments_object);
4705 graph()->SetArgumentsObject(arguments_object);
4718 4706
4719 // First special is HContext. 4707 // First special is HContext.
4720 HInstruction* context = AddInstruction(new(zone()) HContext); 4708 HInstruction* context = AddInstruction(new(zone()) HContext);
4721 environment()->BindContext(context); 4709 environment()->BindContext(context);
4722 4710
4723 // Initialize specials and locals to undefined. 4711 // Initialize specials and locals to undefined.
4724 for (int i = environment()->parameter_count() + 1; 4712 for (int i = environment()->parameter_count() + 1;
4725 i < environment()->length(); 4713 i < environment()->length();
4726 ++i) { 4714 ++i) {
4727 environment()->Bind(i, undefined_constant); 4715 environment()->Bind(i, undefined_constant);
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
5022 // Generate a compare and branch. 5010 // Generate a compare and branch.
5023 CHECK_ALIVE(VisitForValue(clause->label())); 5011 CHECK_ALIVE(VisitForValue(clause->label()));
5024 HValue* label_value = Pop(); 5012 HValue* label_value = Pop();
5025 5013
5026 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 5014 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
5027 HBasicBlock* body_block = graph()->CreateBasicBlock(); 5015 HBasicBlock* body_block = graph()->CreateBasicBlock();
5028 5016
5029 HControlInstruction* compare; 5017 HControlInstruction* compare;
5030 5018
5031 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { 5019 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
5032 if (!clause->IsSmiCompare()) { 5020 if (!clause->compare_type()->Is(Type::Integer31())) {
5033 AddSoftDeoptimize(); 5021 AddSoftDeoptimize();
5034 } 5022 }
5035 5023
5036 HCompareIDAndBranch* compare_ = 5024 HCompareIDAndBranch* compare_ =
5037 new(zone()) HCompareIDAndBranch(tag_value, 5025 new(zone()) HCompareIDAndBranch(tag_value,
5038 label_value, 5026 label_value,
5039 Token::EQ_STRICT); 5027 Token::EQ_STRICT);
5040 compare_->set_observed_input_representation( 5028 compare_->set_observed_input_representation(
5041 Representation::Integer32(), Representation::Integer32()); 5029 Representation::Smi(), Representation::Smi());
5042 compare = compare_; 5030 compare = compare_;
5043 } else { 5031 } else {
5044 compare = new(zone()) HStringCompareAndBranch(context, tag_value, 5032 compare = new(zone()) HStringCompareAndBranch(context, tag_value,
5045 label_value, 5033 label_value,
5046 Token::EQ_STRICT); 5034 Token::EQ_STRICT);
5047 } 5035 }
5048 5036
5049 compare->SetSuccessorAt(0, body_block); 5037 compare->SetSuccessorAt(0, body_block);
5050 compare->SetSuccessorAt(1, next_test_block); 5038 compare->SetSuccessorAt(1, next_test_block);
5051 current_block()->Finish(compare); 5039 current_block()->Finish(compare);
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
5396 set_current_block(loop_entry); 5384 set_current_block(loop_entry);
5397 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); 5385 if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
5398 5386
5399 HValue* index = environment()->ExpressionStackAt(0); 5387 HValue* index = environment()->ExpressionStackAt(0);
5400 HValue* limit = environment()->ExpressionStackAt(1); 5388 HValue* limit = environment()->ExpressionStackAt(1);
5401 5389
5402 // Check that we still have more keys. 5390 // Check that we still have more keys.
5403 HCompareIDAndBranch* compare_index = 5391 HCompareIDAndBranch* compare_index =
5404 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); 5392 new(zone()) HCompareIDAndBranch(index, limit, Token::LT);
5405 compare_index->set_observed_input_representation( 5393 compare_index->set_observed_input_representation(
5406 Representation::Integer32(), Representation::Integer32()); 5394 Representation::Smi(), Representation::Smi());
5407 5395
5408 HBasicBlock* loop_body = graph()->CreateBasicBlock(); 5396 HBasicBlock* loop_body = graph()->CreateBasicBlock();
5409 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); 5397 HBasicBlock* loop_successor = graph()->CreateBasicBlock();
5410 5398
5411 compare_index->SetSuccessorAt(0, loop_body); 5399 compare_index->SetSuccessorAt(0, loop_body);
5412 compare_index->SetSuccessorAt(1, loop_successor); 5400 compare_index->SetSuccessorAt(1, loop_successor);
5413 current_block()->Finish(compare_index); 5401 current_block()->Finish(compare_index);
5414 5402
5415 set_current_block(loop_successor); 5403 set_current_block(loop_successor);
5416 Drop(5); 5404 Drop(5);
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
5618 case Variable::UNALLOCATED: { 5606 case Variable::UNALLOCATED: {
5619 if (IsLexicalVariableMode(variable->mode())) { 5607 if (IsLexicalVariableMode(variable->mode())) {
5620 // TODO(rossberg): should this be an ASSERT? 5608 // TODO(rossberg): should this be an ASSERT?
5621 return Bailout("reference to global lexical variable"); 5609 return Bailout("reference to global lexical variable");
5622 } 5610 }
5623 // Handle known global constants like 'undefined' specially to avoid a 5611 // Handle known global constants like 'undefined' specially to avoid a
5624 // load from a global cell for them. 5612 // load from a global cell for them.
5625 Handle<Object> constant_value = 5613 Handle<Object> constant_value =
5626 isolate()->factory()->GlobalConstantFor(variable->name()); 5614 isolate()->factory()->GlobalConstantFor(variable->name());
5627 if (!constant_value.is_null()) { 5615 if (!constant_value.is_null()) {
5628 HConstant* instr = 5616 HConstant* instr = new(zone()) HConstant(constant_value);
5629 new(zone()) HConstant(constant_value, Representation::Tagged());
5630 return ast_context()->ReturnInstruction(instr, expr->id()); 5617 return ast_context()->ReturnInstruction(instr, expr->id());
5631 } 5618 }
5632 5619
5633 LookupResult lookup(isolate()); 5620 LookupResult lookup(isolate());
5634 GlobalPropertyAccess type = 5621 GlobalPropertyAccess type =
5635 LookupGlobalProperty(variable, &lookup, false); 5622 LookupGlobalProperty(variable, &lookup, false);
5636 5623
5637 if (type == kUseCell && 5624 if (type == kUseCell &&
5638 current_info()->global_object()->IsAccessCheckNeeded()) { 5625 current_info()->global_object()->IsAccessCheckNeeded()) {
5639 type = kUseGeneric; 5626 type = kUseGeneric;
5640 } 5627 }
5641 5628
5642 if (type == kUseCell) { 5629 if (type == kUseCell) {
5643 Handle<GlobalObject> global(current_info()->global_object()); 5630 Handle<GlobalObject> global(current_info()->global_object());
5644 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 5631 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
5645 HLoadGlobalCell* instr = 5632 HLoadGlobalCell* instr =
5646 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); 5633 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails());
5647 return ast_context()->ReturnInstruction(instr, expr->id()); 5634 return ast_context()->ReturnInstruction(instr, expr->id());
5648 } else { 5635 } else {
5649 HValue* context = environment()->LookupContext(); 5636 HValue* context = environment()->LookupContext();
5650 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 5637 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
5651 AddInstruction(global_object); 5638 AddInstruction(global_object);
5652 HLoadGlobalGeneric* instr = 5639 HLoadGlobalGeneric* instr =
5653 new(zone()) HLoadGlobalGeneric(context, 5640 new(zone()) HLoadGlobalGeneric(context,
5654 global_object, 5641 global_object,
(...skipping 24 matching lines...) Expand all
5679 case Variable::LOOKUP: 5666 case Variable::LOOKUP:
5680 return Bailout("reference to a variable which requires dynamic lookup"); 5667 return Bailout("reference to a variable which requires dynamic lookup");
5681 } 5668 }
5682 } 5669 }
5683 5670
5684 5671
5685 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { 5672 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) {
5686 ASSERT(!HasStackOverflow()); 5673 ASSERT(!HasStackOverflow());
5687 ASSERT(current_block() != NULL); 5674 ASSERT(current_block() != NULL);
5688 ASSERT(current_block()->HasPredecessor()); 5675 ASSERT(current_block()->HasPredecessor());
5689 HConstant* instr = 5676 HConstant* instr = new(zone()) HConstant(expr->handle());
5690 new(zone()) HConstant(expr->handle(), Representation::None());
5691 return ast_context()->ReturnInstruction(instr, expr->id()); 5677 return ast_context()->ReturnInstruction(instr, expr->id());
5692 } 5678 }
5693 5679
5694 5680
5695 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 5681 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
5696 ASSERT(!HasStackOverflow()); 5682 ASSERT(!HasStackOverflow());
5697 ASSERT(current_block() != NULL); 5683 ASSERT(current_block() != NULL);
5698 ASSERT(current_block()->HasPredecessor()); 5684 ASSERT(current_block()->HasPredecessor());
5699 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 5685 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
5700 Handle<FixedArray> literals(closure->literals()); 5686 Handle<FixedArray> literals(closure->literals());
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
5905 NoObservableSideEffectsScope no_effects(this); 5891 NoObservableSideEffectsScope no_effects(this);
5906 Handle<FixedArray> closure_literals(closure->literals(), isolate()); 5892 Handle<FixedArray> closure_literals(closure->literals(), isolate());
5907 Handle<FixedArray> constant_properties = expr->constant_properties(); 5893 Handle<FixedArray> constant_properties = expr->constant_properties();
5908 int literal_index = expr->literal_index(); 5894 int literal_index = expr->literal_index();
5909 int flags = expr->fast_elements() 5895 int flags = expr->fast_elements()
5910 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; 5896 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags;
5911 flags |= expr->has_function() 5897 flags |= expr->has_function()
5912 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; 5898 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags;
5913 5899
5914 AddInstruction(new(zone()) HPushArgument(AddInstruction( 5900 AddInstruction(new(zone()) HPushArgument(AddInstruction(
5915 new(zone()) HConstant(closure_literals, Representation::Tagged())))); 5901 new(zone()) HConstant(closure_literals))));
5916 AddInstruction(new(zone()) HPushArgument(AddInstruction( 5902 AddInstruction(new(zone()) HPushArgument(AddInstruction(
5917 new(zone()) HConstant(literal_index, Representation::Tagged())))); 5903 new(zone()) HConstant(literal_index))));
5918 AddInstruction(new(zone()) HPushArgument(AddInstruction( 5904 AddInstruction(new(zone()) HPushArgument(AddInstruction(
5919 new(zone()) HConstant(constant_properties, Representation::Tagged())))); 5905 new(zone()) HConstant(constant_properties))));
5920 AddInstruction(new(zone()) HPushArgument(AddInstruction( 5906 AddInstruction(new(zone()) HPushArgument(AddInstruction(
5921 new(zone()) HConstant(flags, Representation::Tagged())))); 5907 new(zone()) HConstant(flags))));
5922 5908
5923 Runtime::FunctionId function_id = 5909 Runtime::FunctionId function_id =
5924 (expr->depth() > 1 || expr->may_store_doubles()) 5910 (expr->depth() > 1 || expr->may_store_doubles())
5925 ? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow; 5911 ? Runtime::kCreateObjectLiteral : Runtime::kCreateObjectLiteralShallow;
5926 literal = AddInstruction( 5912 literal = AddInstruction(
5927 new(zone()) HCallRuntime(context, 5913 new(zone()) HCallRuntime(context,
5928 isolate()->factory()->empty_string(), 5914 isolate()->factory()->empty_string(),
5929 Runtime::FunctionForId(function_id), 5915 Runtime::FunctionForId(function_id),
5930 4)); 5916 4));
5931 } 5917 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
6059 data_size, 6045 data_size,
6060 pointer_size, 6046 pointer_size,
6061 mode); 6047 mode);
6062 } else { 6048 } else {
6063 NoObservableSideEffectsScope no_effects(this); 6049 NoObservableSideEffectsScope no_effects(this);
6064 // Boilerplate already exists and constant elements are never accessed, 6050 // Boilerplate already exists and constant elements are never accessed,
6065 // pass an empty fixed array to the runtime function instead. 6051 // pass an empty fixed array to the runtime function instead.
6066 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 6052 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
6067 int literal_index = expr->literal_index(); 6053 int literal_index = expr->literal_index();
6068 6054
6069 // TODO(mstarzinger): The following check and deopt is actually obsolete
6070 // but test cases for the tick processor fails because profile differs.
6071
6072 // Deopt if the array literal boilerplate ElementsKind is of a type
6073 // different than the expected one. The check isn't necessary if the
6074 // boilerplate has already been converted to TERMINAL_FAST_ELEMENTS_KIND.
6075 if (CanTransitionToMoreGeneralFastElementsKind(
6076 boilerplate_elements_kind, true)) {
6077 IfBuilder builder(this);
6078 HValue* boilerplate = AddInstruction(new(zone())
6079 HConstant(original_boilerplate_object, Representation::Tagged()));
6080 HValue* elements_kind = AddInstruction(new(zone())
6081 HElementsKind(boilerplate));
6082 HValue* expected_kind = AddInstruction(new(zone())
6083 HConstant(boilerplate_elements_kind, Representation::Integer32()));
6084 builder.IfCompare(elements_kind, expected_kind, Token::EQ);
6085 builder.Then();
6086 builder.ElseDeopt();
6087 }
6088
6089 AddInstruction(new(zone()) HPushArgument(AddInstruction( 6055 AddInstruction(new(zone()) HPushArgument(AddInstruction(
6090 new(zone()) HConstant(literals, Representation::Tagged())))); 6056 new(zone()) HConstant(literals))));
6091 AddInstruction(new(zone()) HPushArgument(AddInstruction( 6057 AddInstruction(new(zone()) HPushArgument(AddInstruction(
6092 new(zone()) HConstant(literal_index, Representation::Tagged())))); 6058 new(zone()) HConstant(literal_index))));
6093 AddInstruction(new(zone()) HPushArgument(AddInstruction( 6059 AddInstruction(new(zone()) HPushArgument(AddInstruction(
6094 new(zone()) HConstant(constants, Representation::Tagged())))); 6060 new(zone()) HConstant(constants))));
6095 6061
6096 Runtime::FunctionId function_id = (expr->depth() > 1) 6062 Runtime::FunctionId function_id = (expr->depth() > 1)
6097 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; 6063 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow;
6098 literal = AddInstruction( 6064 literal = AddInstruction(
6099 new(zone()) HCallRuntime(context, 6065 new(zone()) HCallRuntime(context,
6100 isolate()->factory()->empty_string(), 6066 isolate()->factory()->empty_string(),
6101 Runtime::FunctionForId(function_id), 6067 Runtime::FunctionForId(function_id),
6102 3)); 6068 3));
6103 } 6069 }
6104 6070
6105 // The array is expected in the bailout environment during computation 6071 // The array is expected in the bailout environment during computation
6106 // of the property values and is the value of the entire expression. 6072 // of the property values and is the value of the entire expression.
6107 Push(literal); 6073 Push(literal);
6074 // The literal index is on the stack, too.
6075 Push(AddInstruction(new(zone()) HConstant(expr->literal_index())));
6108 6076
6109 HInstruction* elements = NULL; 6077 HInstruction* elements = NULL;
6110 6078
6111 for (int i = 0; i < length; i++) { 6079 for (int i = 0; i < length; i++) {
6112 Expression* subexpr = subexprs->at(i); 6080 Expression* subexpr = subexprs->at(i);
6113 // If the subexpression is a literal or a simple materialized literal it 6081 // If the subexpression is a literal or a simple materialized literal it
6114 // is already set in the cloned array. 6082 // is already set in the cloned array.
6115 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 6083 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
6116 6084
6117 CHECK_ALIVE(VisitForValue(subexpr)); 6085 CHECK_ALIVE(VisitForValue(subexpr));
(...skipping 17 matching lines...) Expand all
6135 value, 6103 value,
6136 boilerplate_elements_kind)); 6104 boilerplate_elements_kind));
6137 break; 6105 break;
6138 default: 6106 default:
6139 UNREACHABLE(); 6107 UNREACHABLE();
6140 break; 6108 break;
6141 } 6109 }
6142 6110
6143 AddSimulate(expr->GetIdForElement(i)); 6111 AddSimulate(expr->GetIdForElement(i));
6144 } 6112 }
6113
6114 Drop(1); // array literal index
6145 return ast_context()->ReturnValue(Pop()); 6115 return ast_context()->ReturnValue(Pop());
6146 } 6116 }
6147 6117
6148 6118
6149 // Sets the lookup result and returns true if the load/store can be inlined. 6119 // Sets the lookup result and returns true if the load/store can be inlined.
6150 static bool ComputeLoadStoreField(Handle<Map> type, 6120 static bool ComputeLoadStoreField(Handle<Map> type,
6151 Handle<String> name, 6121 Handle<String> name,
6152 LookupResult* lookup, 6122 LookupResult* lookup,
6153 bool is_store) { 6123 bool is_store) {
6154 if (type->has_named_interceptor()) { 6124 if (type->has_named_interceptor()) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
6238 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); 6208 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name);
6239 Representation representation = ComputeLoadStoreRepresentation(map, lookup); 6209 Representation representation = ComputeLoadStoreRepresentation(map, lookup);
6240 bool transition_to_field = lookup->IsTransitionToField(*map); 6210 bool transition_to_field = lookup->IsTransitionToField(*map);
6241 6211
6242 HStoreNamedField *instr; 6212 HStoreNamedField *instr;
6243 if (FLAG_track_double_fields && representation.IsDouble()) { 6213 if (FLAG_track_double_fields && representation.IsDouble()) {
6244 if (transition_to_field) { 6214 if (transition_to_field) {
6245 // The store requires a mutable HeapNumber to be allocated. 6215 // The store requires a mutable HeapNumber to be allocated.
6246 NoObservableSideEffectsScope no_side_effects(this); 6216 NoObservableSideEffectsScope no_side_effects(this);
6247 HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant( 6217 HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant(
6248 HeapNumber::kSize, Representation::Integer32())); 6218 HeapNumber::kSize));
6249 HInstruction* double_box = AddInstruction(new(zone()) HAllocate( 6219 HInstruction* double_box = AddInstruction(new(zone()) HAllocate(
6250 environment()->LookupContext(), heap_number_size, 6220 environment()->LookupContext(), heap_number_size,
6251 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); 6221 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE));
6252 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); 6222 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map());
6253 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 6223 AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
6254 value, Representation::Double()); 6224 value, Representation::Double());
6255 instr = new(zone()) HStoreNamedField(object, field_access, double_box); 6225 instr = new(zone()) HStoreNamedField(object, field_access, double_box);
6256 } else { 6226 } else {
6257 // Already holds a HeapNumber; load the box and write its value field. 6227 // Already holds a HeapNumber; load the box and write its value field.
6258 HInstruction* double_box = AddLoad(object, field_access); 6228 HInstruction* double_box = AddLoad(object, field_access);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
6314 if (ComputeLoadStoreField(map, name, &lookup, true)) { 6284 if (ComputeLoadStoreField(map, name, &lookup, true)) {
6315 AddCheckMapsWithTransitions(object, map); 6285 AddCheckMapsWithTransitions(object, map);
6316 return BuildStoreNamedField(object, name, value, map, &lookup); 6286 return BuildStoreNamedField(object, name, value, map, &lookup);
6317 } 6287 }
6318 6288
6319 // No luck, do a generic store. 6289 // No luck, do a generic store.
6320 return BuildStoreNamedGeneric(object, name, value); 6290 return BuildStoreNamedGeneric(object, name, value);
6321 } 6291 }
6322 6292
6323 6293
6324 bool HOptimizedGraphBuilder::HandlePolymorphicArrayLengthLoad( 6294 HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
6325 Property* expr, 6295 Property* expr,
6326 HValue* object, 6296 HValue* object,
6327 SmallMapList* types, 6297 SmallMapList* types,
6328 Handle<String> name) { 6298 Handle<String> name) {
6329 if (!name->Equals(isolate()->heap()->length_string())) return false;
6330
6331 for (int i = 0; i < types->length(); i++) {
6332 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false;
6333 }
6334
6335 BuildCheckNonSmi(object);
6336
6337 HInstruction* typecheck =
6338 AddInstruction(HCheckMaps::New(object, types, zone()));
6339 HInstruction* instr = new(zone())
6340 HLoadNamedField(object, HObjectAccess::ForArrayLength(), typecheck);
6341
6342 instr->set_position(expr->position());
6343 ast_context()->ReturnInstruction(instr, expr->id());
6344 return true;
6345 }
6346
6347
6348 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
6349 HValue* object,
6350 SmallMapList* types,
6351 Handle<String> name) {
6352
6353 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name))
6354 return;
6355
6356 BuildCheckNonSmi(object);
6357
6358 // Use monomorphic load if property lookup results in the same field index 6299 // Use monomorphic load if property lookup results in the same field index
6359 // for all maps. Requires special map check on the set of all handled maps. 6300 // for all maps. Requires special map check on the set of all handled maps.
6360 HInstruction* instr = NULL; 6301 if (types->length() > kMaxLoadPolymorphism) return NULL;
6302
6361 LookupResult lookup(isolate()); 6303 LookupResult lookup(isolate());
6362 int count; 6304 int count;
6363 Representation representation = Representation::None(); 6305 Representation representation = Representation::None();
6364 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. 6306 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
6365 for (count = 0; 6307 for (count = 0; count < types->length(); ++count) {
6366 count < types->length() && count < kMaxLoadPolymorphism;
6367 ++count) {
6368 Handle<Map> map = types->at(count); 6308 Handle<Map> map = types->at(count);
6369 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; 6309 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
6370 6310
6371 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); 6311 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
6312 Representation new_representation =
6313 ComputeLoadStoreRepresentation(map, &lookup);
6314
6315 if (count == 0) {
6316 // First time through the loop; set access and representation.
6317 access = new_access;
6318 } else if (!representation.IsCompatibleForLoad(new_representation)) {
6319 // Representations did not match.
6320 break;
6321 } else if (access.offset() != new_access.offset()) {
6322 // Offsets did not match.
6323 break;
6324 } else if (access.IsInobject() != new_access.IsInobject()) {
6325 // In-objectness did not match.
6326 break;
6327 }
6328 representation = representation.generalize(new_representation);
6329 }
6330
6331 if (count != types->length()) return NULL;
6332
6333 // Everything matched; can use monomorphic load.
6334 BuildCheckNonSmi(object);
6335 AddInstruction(HCheckMaps::New(object, types, zone()));
6336 return BuildLoadNamedField(object, access, representation);
6337 }
6338
6339
6340 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
6341 Property* expr,
6342 HValue* object,
6343 SmallMapList* types,
6344 Handle<String> name) {
6345 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(
6346 expr, object, types, name);
6347 if (instr == NULL) {
6348 // Something did not match; must use a polymorphic load.
6349 BuildCheckNonSmi(object);
6350 HValue* context = environment()->LookupContext();
6351 instr = new(zone()) HLoadNamedFieldPolymorphic(
6352 context, object, types, name, zone());
6353 }
6354
6355 instr->set_position(expr->position());
6356 return ast_context()->ReturnInstruction(instr, expr->id());
6357 }
6358
6359
6360 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
6361 Assignment* expr,
6362 HValue* object,
6363 HValue* value,
6364 SmallMapList* types,
6365 Handle<String> name) {
6366 // Use monomorphic store if property lookup results in the same field index
6367 // for all maps. Requires special map check on the set of all handled maps.
6368 if (types->length() > kMaxStorePolymorphism) return false;
6369
6370 // TODO(verwaest): Merge the checking logic with the code in
6371 // TryLoadPolymorphicAsMonomorphic.
6372 LookupResult lookup(isolate());
6373 int count;
6374 Representation representation = Representation::None();
6375 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
6376 for (count = 0; count < types->length(); ++count) {
6377 Handle<Map> map = types->at(count);
6378 // Pass false to ignore transitions.
6379 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
6380
6381 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
6372 Representation new_representation = 6382 Representation new_representation =
6373 ComputeLoadStoreRepresentation(map, &lookup); 6383 ComputeLoadStoreRepresentation(map, &lookup);
6374 6384
6375 if (count == 0) { 6385 if (count == 0) {
6376 // First time through the loop; set access and representation. 6386 // First time through the loop; set access and representation.
6377 access = new_access; 6387 access = new_access;
6378 representation = new_representation; 6388 representation = new_representation;
6379 } else if (!representation.IsCompatibleForLoad(new_representation)) { 6389 } else if (!representation.IsCompatibleForStore(new_representation)) {
6380 // Representations did not match. 6390 // Representations did not match.
6381 break; 6391 break;
6382 } else if (access.offset() != new_access.offset()) { 6392 } else if (access.offset() != new_access.offset()) {
6383 // Offsets did not match. 6393 // Offsets did not match.
6384 break; 6394 break;
6385 } else if (access.IsInobject() != new_access.IsInobject()) { 6395 } else if (access.IsInobject() != new_access.IsInobject()) {
6386 // In-objectness did not match. 6396 // In-objectness did not match.
6387 break; 6397 break;
6388 } 6398 }
6389 } 6399 }
6390 6400
6391 if (count == types->length()) { 6401 if (count != types->length()) return false;
6392 // Everything matched; can use monomorphic load.
6393 AddInstruction(HCheckMaps::New(object, types, zone()));
6394 instr = BuildLoadNamedField(object, access, representation);
6395 } else {
6396 // Something did not match; must use a polymorphic load.
6397 HValue* context = environment()->LookupContext();
6398 instr = new(zone()) HLoadNamedFieldPolymorphic(
6399 context, object, types, name, zone());
6400 }
6401 6402
6402 instr->set_position(expr->position()); 6403 // Everything matched; can use monomorphic store.
6403 return ast_context()->ReturnInstruction(instr, expr->id()); 6404 BuildCheckNonSmi(object);
6405 AddInstruction(HCheckMaps::New(object, types, zone()));
6406 HInstruction* store;
6407 CHECK_ALIVE_OR_RETURN(
6408 store = BuildStoreNamedField(object, name, value, types->at(0), &lookup),
6409 true);
6410 Push(value);
6411 store->set_position(expr->position());
6412 AddInstruction(store);
6413 AddSimulate(expr->AssignmentId());
6414 ast_context()->ReturnValue(Pop());
6415 return true;
6404 } 6416 }
6405 6417
6406 6418
6407 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 6419 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
6408 Assignment* expr, 6420 Assignment* expr,
6409 HValue* object, 6421 HValue* object,
6410 HValue* value, 6422 HValue* value,
6411 SmallMapList* types, 6423 SmallMapList* types,
6412 Handle<String> name) { 6424 Handle<String> name) {
6425 if (TryStorePolymorphicAsMonomorphic(expr, object, value, types, name)) {
6426 return;
6427 }
6428
6413 // TODO(ager): We should recognize when the prototype chains for different 6429 // TODO(ager): We should recognize when the prototype chains for different
6414 // maps are identical. In that case we can avoid repeatedly generating the 6430 // maps are identical. In that case we can avoid repeatedly generating the
6415 // same prototype map checks. 6431 // same prototype map checks.
6416 int count = 0; 6432 int count = 0;
6417 HBasicBlock* join = NULL; 6433 HBasicBlock* join = NULL;
6418 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 6434 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
6419 Handle<Map> map = types->at(i); 6435 Handle<Map> map = types->at(i);
6420 LookupResult lookup(isolate()); 6436 LookupResult lookup(isolate());
6421 if (ComputeLoadStoreField(map, name, &lookup, true)) { 6437 if (ComputeLoadStoreField(map, name, &lookup, true)) {
6422 if (count == 0) { 6438 if (count == 0) {
6423 BuildCheckNonSmi(object); 6439 BuildCheckNonSmi(object);
6424 join = graph()->CreateBasicBlock(); 6440 join = graph()->CreateBasicBlock();
6425 } 6441 }
6426 ++count; 6442 ++count;
6427 HBasicBlock* if_true = graph()->CreateBasicBlock(); 6443 HBasicBlock* if_true = graph()->CreateBasicBlock();
6428 HBasicBlock* if_false = graph()->CreateBasicBlock(); 6444 HBasicBlock* if_false = graph()->CreateBasicBlock();
6429 HCompareMap* compare = 6445 HCompareMap* compare =
6430 new(zone()) HCompareMap(object, map, if_true, if_false); 6446 new(zone()) HCompareMap(object, map, if_true, if_false);
6431 current_block()->Finish(compare); 6447 current_block()->Finish(compare);
6432 6448
6433 set_current_block(if_true); 6449 set_current_block(if_true);
6434 HInstruction* instr; 6450 HInstruction* instr;
6435 CHECK_ALIVE(instr = 6451 CHECK_ALIVE(
6436 BuildStoreNamedField(object, name, value, map, &lookup)); 6452 instr = BuildStoreNamedField(object, name, value, map, &lookup));
6437 instr->set_position(expr->position()); 6453 instr->set_position(expr->position());
6438 // Goto will add the HSimulate for the store. 6454 // Goto will add the HSimulate for the store.
6439 AddInstruction(instr); 6455 AddInstruction(instr);
6440 if (!ast_context()->IsEffect()) Push(value); 6456 if (!ast_context()->IsEffect()) Push(value);
6441 current_block()->Goto(join); 6457 current_block()->Goto(join);
6442 6458
6443 set_current_block(if_false); 6459 set_current_block(if_false);
6444 } 6460 }
6445 } 6461 }
6446 6462
(...skipping 23 matching lines...) Expand all
6470 Drop(1); 6486 Drop(1);
6471 } 6487 }
6472 } 6488 }
6473 return ast_context()->ReturnValue(value); 6489 return ast_context()->ReturnValue(value);
6474 } 6490 }
6475 } 6491 }
6476 6492
6477 ASSERT(join != NULL); 6493 ASSERT(join != NULL);
6478 join->SetJoinId(expr->id()); 6494 join->SetJoinId(expr->id());
6479 set_current_block(join); 6495 set_current_block(join);
6480 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); 6496 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6481 } 6497 }
6482 6498
6483 6499
6484 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 6500 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
6485 Property* prop = expr->target()->AsProperty(); 6501 Property* prop = expr->target()->AsProperty();
6486 ASSERT(prop != NULL); 6502 ASSERT(prop != NULL);
6487 CHECK_ALIVE(VisitForValue(prop->obj())); 6503 CHECK_ALIVE(VisitForValue(prop->obj()));
6488 6504
6489 if (prop->key()->IsPropertyName()) { 6505 if (prop->key()->IsPropertyName()) {
6490 // Named store. 6506 // Named store.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
6565 // owning expression instead of position and ast_id separately. 6581 // owning expression instead of position and ast_id separately.
6566 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( 6582 void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
6567 Variable* var, 6583 Variable* var,
6568 HValue* value, 6584 HValue* value,
6569 int position, 6585 int position,
6570 BailoutId ast_id) { 6586 BailoutId ast_id) {
6571 LookupResult lookup(isolate()); 6587 LookupResult lookup(isolate());
6572 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); 6588 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
6573 if (type == kUseCell) { 6589 if (type == kUseCell) {
6574 Handle<GlobalObject> global(current_info()->global_object()); 6590 Handle<GlobalObject> global(current_info()->global_object());
6575 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 6591 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
6576 HInstruction* instr = 6592 HInstruction* instr =
6577 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); 6593 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails());
6578 instr->set_position(position); 6594 instr->set_position(position);
6579 AddInstruction(instr); 6595 AddInstruction(instr);
6580 if (instr->HasObservableSideEffects()) { 6596 if (instr->HasObservableSideEffects()) {
6581 AddSimulate(ast_id, REMOVABLE_SIMULATE); 6597 AddSimulate(ast_id, REMOVABLE_SIMULATE);
6582 } 6598 }
6583 } else { 6599 } else {
6584 HValue* context = environment()->LookupContext(); 6600 HValue* context = environment()->LookupContext();
6585 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 6601 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
6681 return ast_context()->ReturnValue(Pop()); 6697 return ast_context()->ReturnValue(Pop());
6682 6698
6683 } else if (prop != NULL) { 6699 } else if (prop != NULL) {
6684 if (prop->key()->IsPropertyName()) { 6700 if (prop->key()->IsPropertyName()) {
6685 // Named property. 6701 // Named property.
6686 CHECK_ALIVE(VisitForValue(prop->obj())); 6702 CHECK_ALIVE(VisitForValue(prop->obj()));
6687 HValue* object = Top(); 6703 HValue* object = Top();
6688 6704
6689 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 6705 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
6690 Handle<Map> map; 6706 Handle<Map> map;
6691 HInstruction* load; 6707 HInstruction* load = NULL;
6708 SmallMapList* types = prop->GetReceiverTypes();
6692 bool monomorphic = prop->IsMonomorphic(); 6709 bool monomorphic = prop->IsMonomorphic();
6693 if (monomorphic) { 6710 if (monomorphic) {
6694 map = prop->GetReceiverTypes()->first(); 6711 map = types->first();
6695 // We can't generate code for a monomorphic dict mode load so 6712 // We can't generate code for a monomorphic dict mode load so
6696 // just pretend it is not monomorphic. 6713 // just pretend it is not monomorphic.
6697 if (map->is_dictionary_map()) monomorphic = false; 6714 if (map->is_dictionary_map()) monomorphic = false;
6698 } 6715 }
6699 if (monomorphic) { 6716 if (monomorphic) {
6700 Handle<JSFunction> getter; 6717 Handle<JSFunction> getter;
6701 Handle<JSObject> holder; 6718 Handle<JSObject> holder;
6702 if (LookupGetter(map, name, &getter, &holder)) { 6719 if (LookupGetter(map, name, &getter, &holder)) {
6703 load = BuildCallGetter(object, map, getter, holder); 6720 load = BuildCallGetter(object, map, getter, holder);
6704 } else { 6721 } else {
6705 load = BuildLoadNamedMonomorphic(object, name, prop, map); 6722 load = BuildLoadNamedMonomorphic(object, name, prop, map);
6706 } 6723 }
6707 } else { 6724 } else if (types != NULL && types->length() > 1) {
6708 load = BuildLoadNamedGeneric(object, name, prop); 6725 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
6709 } 6726 }
6727 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
6710 PushAndAdd(load); 6728 PushAndAdd(load);
6711 if (load->HasObservableSideEffects()) { 6729 if (load->HasObservableSideEffects()) {
6712 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 6730 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
6713 } 6731 }
6714 6732
6715 CHECK_ALIVE(VisitForValue(expr->value())); 6733 CHECK_ALIVE(VisitForValue(expr->value()));
6716 HValue* right = Pop(); 6734 HValue* right = Pop();
6717 HValue* left = Pop(); 6735 HValue* left = Pop();
6718 6736
6719 HInstruction* instr = BuildBinaryOperation(operation, left, right); 6737 HInstruction* instr = BuildBinaryOperation(operation, left, right);
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
6965 return field; 6983 return field;
6966 } 6984 }
6967 6985
6968 6986
6969 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 6987 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
6970 HValue* object, 6988 HValue* object,
6971 Handle<String> name, 6989 Handle<String> name,
6972 Property* expr) { 6990 Property* expr) {
6973 if (expr->IsUninitialized()) { 6991 if (expr->IsUninitialized()) {
6974 AddSoftDeoptimize(); 6992 AddSoftDeoptimize();
6993 } else {
6994 // OS::DebugBreak();
6975 } 6995 }
6976 HValue* context = environment()->LookupContext(); 6996 HValue* context = environment()->LookupContext();
6977 return new(zone()) HLoadNamedGeneric(context, object, name); 6997 return new(zone()) HLoadNamedGeneric(context, object, name);
6978 } 6998 }
6979 6999
6980 7000
6981 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( 7001 HInstruction* HOptimizedGraphBuilder::BuildCallGetter(
6982 HValue* object, 7002 HValue* object,
6983 Handle<Map> map, 7003 Handle<Map> map,
6984 Handle<JSFunction> getter, 7004 Handle<JSFunction> getter,
(...skipping 27 matching lines...) Expand all
7012 AddCheckMap(object, map); 7032 AddCheckMap(object, map);
7013 return BuildLoadNamedField(object, 7033 return BuildLoadNamedField(object,
7014 HObjectAccess::ForField(map, &lookup, name), 7034 HObjectAccess::ForField(map, &lookup, name),
7015 ComputeLoadStoreRepresentation(map, &lookup)); 7035 ComputeLoadStoreRepresentation(map, &lookup));
7016 } 7036 }
7017 7037
7018 // Handle a load of a constant known function. 7038 // Handle a load of a constant known function.
7019 if (lookup.IsConstantFunction()) { 7039 if (lookup.IsConstantFunction()) {
7020 AddCheckMap(object, map); 7040 AddCheckMap(object, map);
7021 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); 7041 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
7022 return new(zone()) HConstant(function, Representation::Tagged()); 7042 return new(zone()) HConstant(function);
7023 } 7043 }
7024 7044
7025 // Handle a load from a known field somewhere in the prototype chain. 7045 // Handle a load from a known field somewhere in the prototype chain.
7026 LookupInPrototypes(map, name, &lookup); 7046 LookupInPrototypes(map, name, &lookup);
7027 if (lookup.IsField()) { 7047 if (lookup.IsField()) {
7028 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 7048 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
7029 Handle<JSObject> holder(lookup.holder()); 7049 Handle<JSObject> holder(lookup.holder());
7030 Handle<Map> holder_map(holder->map()); 7050 Handle<Map> holder_map(holder->map());
7031 AddCheckMap(object, map); 7051 AddCheckMap(object, map);
7032 AddInstruction(new(zone()) HCheckPrototypeMaps( 7052 AddInstruction(new(zone()) HCheckPrototypeMaps(
7033 prototype, holder, zone(), top_info())); 7053 prototype, holder, zone(), top_info()));
7034 HValue* holder_value = AddInstruction(new(zone()) 7054 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder));
7035 HConstant(holder, Representation::Tagged()));
7036 return BuildLoadNamedField(holder_value, 7055 return BuildLoadNamedField(holder_value,
7037 HObjectAccess::ForField(holder_map, &lookup, name), 7056 HObjectAccess::ForField(holder_map, &lookup, name),
7038 ComputeLoadStoreRepresentation(map, &lookup)); 7057 ComputeLoadStoreRepresentation(map, &lookup));
7039 } 7058 }
7040 7059
7041 // Handle a load of a constant function somewhere in the prototype chain. 7060 // Handle a load of a constant function somewhere in the prototype chain.
7042 if (lookup.IsConstantFunction()) { 7061 if (lookup.IsConstantFunction()) {
7043 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 7062 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
7044 Handle<JSObject> holder(lookup.holder()); 7063 Handle<JSObject> holder(lookup.holder());
7045 Handle<Map> holder_map(holder->map()); 7064 Handle<Map> holder_map(holder->map());
7046 AddCheckMap(object, map); 7065 AddCheckMap(object, map);
7047 AddInstruction(new(zone()) HCheckPrototypeMaps( 7066 AddInstruction(new(zone()) HCheckPrototypeMaps(
7048 prototype, holder, zone(), top_info())); 7067 prototype, holder, zone(), top_info()));
7049 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); 7068 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map));
7050 return new(zone()) HConstant(function, Representation::Tagged()); 7069 return new(zone()) HConstant(function);
7051 } 7070 }
7052 7071
7053 // No luck, do a generic load. 7072 // No luck, do a generic load.
7054 return BuildLoadNamedGeneric(object, name, expr); 7073 return BuildLoadNamedGeneric(object, name, expr);
7055 } 7074 }
7056 7075
7057 7076
7058 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, 7077 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object,
7059 HValue* key) { 7078 HValue* key) {
7060 HValue* context = environment()->LookupContext(); 7079 HValue* context = environment()->LookupContext();
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
7427 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { 7446 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() {
7428 // Outermost function already has arguments on the stack. 7447 // Outermost function already has arguments on the stack.
7429 if (function_state()->outer() == NULL) return; 7448 if (function_state()->outer() == NULL) return;
7430 7449
7431 if (function_state()->arguments_pushed()) return; 7450 if (function_state()->arguments_pushed()) return;
7432 7451
7433 // Push arguments when entering inlined function. 7452 // Push arguments when entering inlined function.
7434 HEnterInlined* entry = function_state()->entry(); 7453 HEnterInlined* entry = function_state()->entry();
7435 entry->set_arguments_pushed(); 7454 entry->set_arguments_pushed();
7436 7455
7437 ZoneList<HValue*>* arguments_values = entry->arguments_values(); 7456 HArgumentsObject* arguments = entry->arguments_object();
7457 const ZoneList<HValue*>* arguments_values = arguments->arguments_values();
7438 7458
7439 HInstruction* insert_after = entry; 7459 HInstruction* insert_after = entry;
7440 for (int i = 0; i < arguments_values->length(); i++) { 7460 for (int i = 0; i < arguments_values->length(); i++) {
7441 HValue* argument = arguments_values->at(i); 7461 HValue* argument = arguments_values->at(i);
7442 HInstruction* push_argument = new(zone()) HPushArgument(argument); 7462 HInstruction* push_argument = new(zone()) HPushArgument(argument);
7443 push_argument->InsertAfter(insert_after); 7463 push_argument->InsertAfter(insert_after);
7444 insert_after = push_argument; 7464 insert_after = push_argument;
7445 } 7465 }
7446 7466
7447 HArgumentsElements* arguments_elements = 7467 HArgumentsElements* arguments_elements =
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
7995 &target_info, 8015 &target_info,
7996 target_shared); 8016 target_shared);
7997 } 8017 }
7998 8018
7999 // ---------------------------------------------------------------- 8019 // ----------------------------------------------------------------
8000 // After this point, we've made a decision to inline this function (so 8020 // After this point, we've made a decision to inline this function (so
8001 // TryInline should always return true). 8021 // TryInline should always return true).
8002 8022
8003 // Type-check the inlined function. 8023 // Type-check the inlined function.
8004 ASSERT(target_shared->has_deoptimization_support()); 8024 ASSERT(target_shared->has_deoptimization_support());
8005 AstTyper::Type(&target_info); 8025 AstTyper::Run(&target_info);
8006 8026
8007 // Save the pending call context. Set up new one for the inlined function. 8027 // Save the pending call context. Set up new one for the inlined function.
8008 // The function state is new-allocated because we need to delete it 8028 // The function state is new-allocated because we need to delete it
8009 // in two different places. 8029 // in two different places.
8010 FunctionState* target_state = new FunctionState( 8030 FunctionState* target_state = new FunctionState(
8011 this, &target_info, inlining_kind); 8031 this, &target_info, inlining_kind);
8012 8032
8013 HConstant* undefined = graph()->GetConstantUndefined(); 8033 HConstant* undefined = graph()->GetConstantUndefined();
8014 bool undefined_receiver = HEnvironment::UseUndefinedReceiver( 8034 bool undefined_receiver = HEnvironment::UseUndefinedReceiver(
8015 target, function, call_kind, inlining_kind); 8035 target, function, call_kind, inlining_kind);
8016 HEnvironment* inner_env = 8036 HEnvironment* inner_env =
8017 environment()->CopyForInlining(target, 8037 environment()->CopyForInlining(target,
8018 arguments_count, 8038 arguments_count,
8019 function, 8039 function,
8020 undefined, 8040 undefined,
8021 function_state()->inlining_kind(), 8041 function_state()->inlining_kind(),
8022 undefined_receiver); 8042 undefined_receiver);
8023 #ifdef V8_TARGET_ARCH_IA32 8043 #ifdef V8_TARGET_ARCH_IA32
8024 // IA32 only, overwrite the caller's context in the deoptimization 8044 // IA32 only, overwrite the caller's context in the deoptimization
8025 // environment with the correct one. 8045 // environment with the correct one.
8026 // 8046 //
8027 // TODO(kmillikin): implement the same inlining on other platforms so we 8047 // TODO(kmillikin): implement the same inlining on other platforms so we
8028 // can remove the unsightly ifdefs in this function. 8048 // can remove the unsightly ifdefs in this function.
8029 HConstant* context = 8049 HConstant* context =
8030 new(zone()) HConstant(Handle<Context>(target->context()), 8050 new(zone()) HConstant(Handle<Context>(target->context()));
8031 Representation::Tagged());
8032 AddInstruction(context); 8051 AddInstruction(context);
8033 inner_env->BindContext(context); 8052 inner_env->BindContext(context);
8034 #endif 8053 #endif
8035 8054
8036 AddSimulate(return_id); 8055 AddSimulate(return_id);
8037 current_block()->UpdateEnvironment(inner_env); 8056 current_block()->UpdateEnvironment(inner_env);
8038 ZoneList<HValue*>* arguments_values = NULL; 8057 HArgumentsObject* arguments_object = NULL;
8039 8058
8040 // If the function uses arguments copy current arguments values 8059 // If the function uses arguments object create and bind one, also copy
8041 // to use them for materialization. 8060 // current arguments values to use them for materialization.
8042 if (function->scope()->arguments() != NULL) { 8061 if (function->scope()->arguments() != NULL) {
8062 ASSERT(function->scope()->arguments()->IsStackAllocated());
8043 HEnvironment* arguments_env = inner_env->arguments_environment(); 8063 HEnvironment* arguments_env = inner_env->arguments_environment();
8044 int arguments_count = arguments_env->parameter_count(); 8064 int arguments_count = arguments_env->parameter_count();
8045 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); 8065 arguments_object = new(zone()) HArgumentsObject(arguments_count, zone());
8066 inner_env->Bind(function->scope()->arguments(), arguments_object);
8046 for (int i = 0; i < arguments_count; i++) { 8067 for (int i = 0; i < arguments_count; i++) {
8047 arguments_values->Add(arguments_env->Lookup(i), zone()); 8068 arguments_object->AddArgument(arguments_env->Lookup(i), zone());
8048 } 8069 }
8070 AddInstruction(arguments_object);
8049 } 8071 }
8050 8072
8051 HEnterInlined* enter_inlined = 8073 HEnterInlined* enter_inlined =
8052 new(zone()) HEnterInlined(target, 8074 new(zone()) HEnterInlined(target,
8053 arguments_count, 8075 arguments_count,
8054 function, 8076 function,
8055 function_state()->inlining_kind(), 8077 function_state()->inlining_kind(),
8056 function->scope()->arguments(), 8078 function->scope()->arguments(),
8057 arguments_values, 8079 arguments_object,
8058 undefined_receiver, 8080 undefined_receiver,
8059 zone()); 8081 zone());
8060 function_state()->set_entry(enter_inlined); 8082 function_state()->set_entry(enter_inlined);
8061 AddInstruction(enter_inlined); 8083 AddInstruction(enter_inlined);
8062 8084
8063 // If the function uses arguments object create and bind one.
8064 if (function->scope()->arguments() != NULL) {
8065 ASSERT(function->scope()->arguments()->IsStackAllocated());
8066 inner_env->Bind(function->scope()->arguments(),
8067 graph()->GetArgumentsObject());
8068 }
8069
8070
8071 VisitDeclarations(target_info.scope()->declarations()); 8085 VisitDeclarations(target_info.scope()->declarations());
8072 VisitStatements(function->body()); 8086 VisitStatements(function->body());
8073 if (HasStackOverflow()) { 8087 if (HasStackOverflow()) {
8074 // Bail out if the inline function did, as we cannot residualize a call 8088 // Bail out if the inline function did, as we cannot residualize a call
8075 // instead. 8089 // instead.
8076 TraceInline(target, caller, "inline graph construction failed"); 8090 TraceInline(target, caller, "inline graph construction failed");
8077 target_shared->DisableOptimization("inlining bailed out"); 8091 target_shared->DisableOptimization("inlining bailed out");
8078 inline_bailout_ = true; 8092 inline_bailout_ = true;
8079 delete target_state; 8093 delete target_state;
8080 return true; 8094 return true;
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
8366 Pop(); // Pop receiver. 8380 Pop(); // Pop receiver.
8367 HValue* context = environment()->LookupContext(); 8381 HValue* context = environment()->LookupContext();
8368 HInstruction* result = NULL; 8382 HInstruction* result = NULL;
8369 // Use sqrt() if exponent is 0.5 or -0.5. 8383 // Use sqrt() if exponent is 0.5 or -0.5.
8370 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { 8384 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) {
8371 double exponent = HConstant::cast(right)->DoubleValue(); 8385 double exponent = HConstant::cast(right)->DoubleValue();
8372 if (exponent == 0.5) { 8386 if (exponent == 0.5) {
8373 result = 8387 result =
8374 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); 8388 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf);
8375 } else if (exponent == -0.5) { 8389 } else if (exponent == -0.5) {
8376 HConstant* double_one = new(zone()) HConstant( 8390 HValue* one = graph()->GetConstant1();
8377 1, Representation::Double());
8378 AddInstruction(double_one);
8379 HInstruction* sqrt = 8391 HInstruction* sqrt =
8380 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); 8392 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf);
8381 AddInstruction(sqrt); 8393 AddInstruction(sqrt);
8382 // MathPowHalf doesn't have side effects so there's no need for 8394 // MathPowHalf doesn't have side effects so there's no need for
8383 // an environment simulation here. 8395 // an environment simulation here.
8384 ASSERT(!sqrt->HasObservableSideEffects()); 8396 ASSERT(!sqrt->HasObservableSideEffects());
8385 result = HDiv::New(zone(), context, double_one, sqrt); 8397 result = HDiv::New(zone(), context, one, sqrt);
8386 } else if (exponent == 2.0) { 8398 } else if (exponent == 2.0) {
8387 result = HMul::New(zone(), context, left, left); 8399 result = HMul::New(zone(), context, left, left);
8388 } 8400 }
8389 } else if (right->EqualsInteger32Constant(2)) { 8401 } else if (right->EqualsInteger32Constant(2)) {
8390 result = HMul::New(zone(), context, left, left); 8402 result = HMul::New(zone(), context, left, left);
8391 } 8403 }
8392 8404
8393 if (result == NULL) { 8405 if (result == NULL) {
8394 result = HPower::New(zone(), left, right); 8406 result = HPower::New(zone(), left, right);
8395 } 8407 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
8492 new(zone()) HApplyArguments(function, 8504 new(zone()) HApplyArguments(function,
8493 wrapped_receiver, 8505 wrapped_receiver,
8494 length, 8506 length,
8495 elements); 8507 elements);
8496 result->set_position(expr->position()); 8508 result->set_position(expr->position());
8497 ast_context()->ReturnInstruction(result, expr->id()); 8509 ast_context()->ReturnInstruction(result, expr->id());
8498 return true; 8510 return true;
8499 } else { 8511 } else {
8500 // We are inside inlined function and we know exactly what is inside 8512 // We are inside inlined function and we know exactly what is inside
8501 // arguments object. But we need to be able to materialize at deopt. 8513 // arguments object. But we need to be able to materialize at deopt.
8502 // TODO(mstarzinger): For now we just ensure arguments are pushed
8503 // right after HEnterInlined, but we could be smarter about this.
8504 EnsureArgumentsArePushedForAccess();
8505 ASSERT_EQ(environment()->arguments_environment()->parameter_count(), 8514 ASSERT_EQ(environment()->arguments_environment()->parameter_count(),
8506 function_state()->entry()->arguments_values()->length()); 8515 function_state()->entry()->arguments_object()->arguments_count());
8507 HEnterInlined* entry = function_state()->entry(); 8516 HArgumentsObject* args = function_state()->entry()->arguments_object();
8508 ZoneList<HValue*>* arguments_values = entry->arguments_values(); 8517 const ZoneList<HValue*>* arguments_values = args->arguments_values();
8509 int arguments_count = arguments_values->length(); 8518 int arguments_count = arguments_values->length();
8510 PushAndAdd(new(zone()) HWrapReceiver(receiver, function)); 8519 PushAndAdd(new(zone()) HWrapReceiver(receiver, function));
8511 for (int i = 1; i < arguments_count; i++) { 8520 for (int i = 1; i < arguments_count; i++) {
8512 Push(arguments_values->at(i)); 8521 Push(arguments_values->at(i));
8513 } 8522 }
8514 8523
8515 Handle<JSFunction> known_function; 8524 Handle<JSFunction> known_function;
8516 if (function->IsConstant()) { 8525 if (function->IsConstant()) {
8517 HConstant* constant_function = HConstant::cast(function); 8526 HConstant* constant_function = HConstant::cast(function);
8518 known_function = Handle<JSFunction>::cast(constant_function->handle()); 8527 known_function = Handle<JSFunction>::cast(constant_function->handle());
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
8734 PrintF("\n"); 8743 PrintF("\n");
8735 } 8744 }
8736 return; 8745 return;
8737 } 8746 }
8738 if (TryInlineCall(expr)) return; 8747 if (TryInlineCall(expr)) return;
8739 8748
8740 if (expr->target().is_identical_to(current_info()->closure())) { 8749 if (expr->target().is_identical_to(current_info()->closure())) {
8741 graph()->MarkRecursive(); 8750 graph()->MarkRecursive();
8742 } 8751 }
8743 8752
8744 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), 8753 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) {
8754 // When the target has a custom call IC generator, use the IC,
8755 // because it is likely to generate better code.
8756 HValue* context = environment()->LookupContext();
8757 call = PreProcessCall(
8758 new(zone()) HCallNamed(context, var->name(), argument_count));
8759 } else {
8760 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
8745 argument_count)); 8761 argument_count));
8762 }
8746 } else { 8763 } else {
8747 HValue* context = environment()->LookupContext(); 8764 HValue* context = environment()->LookupContext();
8748 HGlobalObject* receiver = new(zone()) HGlobalObject(context); 8765 HGlobalObject* receiver = new(zone()) HGlobalObject(context);
8749 AddInstruction(receiver); 8766 AddInstruction(receiver);
8750 PushAndAdd(new(zone()) HPushArgument(receiver)); 8767 PushAndAdd(new(zone()) HPushArgument(receiver));
8751 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 8768 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
8752 8769
8753 call = new(zone()) HCallGlobal(context, var->name(), argument_count); 8770 call = new(zone()) HCallGlobal(context, var->name(), argument_count);
8754 Drop(argument_count); 8771 Drop(argument_count);
8755 } 8772 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
8844 } 8861 }
8845 8862
8846 // Calculate instance size from initial map of constructor. 8863 // Calculate instance size from initial map of constructor.
8847 ASSERT(constructor->has_initial_map()); 8864 ASSERT(constructor->has_initial_map());
8848 Handle<Map> initial_map(constructor->initial_map()); 8865 Handle<Map> initial_map(constructor->initial_map());
8849 int instance_size = initial_map->instance_size(); 8866 int instance_size = initial_map->instance_size();
8850 ASSERT(initial_map->InitialPropertiesLength() == 0); 8867 ASSERT(initial_map->InitialPropertiesLength() == 0);
8851 8868
8852 // Allocate an instance of the implicit receiver object. 8869 // Allocate an instance of the implicit receiver object.
8853 HValue* size_in_bytes = 8870 HValue* size_in_bytes =
8854 AddInstruction(new(zone()) HConstant(instance_size, 8871 AddInstruction(new(zone()) HConstant(instance_size));
8855 Representation::Integer32()));
8856 8872
8857 HAllocate::Flags flags = HAllocate::DefaultFlags(); 8873 HAllocate::Flags flags = HAllocate::DefaultFlags();
8858 if (FLAG_pretenuring_call_new && 8874 if (FLAG_pretenuring_call_new &&
8859 isolate()->heap()->ShouldGloballyPretenure()) { 8875 isolate()->heap()->ShouldGloballyPretenure()) {
8860 flags = static_cast<HAllocate::Flags>( 8876 flags = static_cast<HAllocate::Flags>(
8861 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 8877 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
8862 } 8878 }
8863 8879
8864 HInstruction* receiver = 8880 HInstruction* receiver =
8865 AddInstruction(new(zone()) HAllocate(context, 8881 AddInstruction(new(zone()) HAllocate(context,
8866 size_in_bytes, 8882 size_in_bytes,
8867 HType::JSObject(), 8883 HType::JSObject(),
8868 flags)); 8884 flags));
8869 HAllocate::cast(receiver)->set_known_initial_map(initial_map); 8885 HAllocate::cast(receiver)->set_known_initial_map(initial_map);
8870 8886
8871 // Load the initial map from the constructor. 8887 // Load the initial map from the constructor.
8872 HValue* constructor_value = 8888 HValue* constructor_value =
8873 AddInstruction(new(zone()) HConstant(constructor, 8889 AddInstruction(new(zone()) HConstant(constructor));
8874 Representation::Tagged()));
8875 HValue* initial_map_value = 8890 HValue* initial_map_value =
8876 AddLoad(constructor_value, HObjectAccess::ForJSObjectOffset( 8891 AddLoad(constructor_value, HObjectAccess::ForJSObjectOffset(
8877 JSFunction::kPrototypeOrInitialMapOffset)); 8892 JSFunction::kPrototypeOrInitialMapOffset));
8878 8893
8879 // Initialize map and fields of the newly allocated object. 8894 // Initialize map and fields of the newly allocated object.
8880 { NoObservableSideEffectsScope no_effects(this); 8895 { NoObservableSideEffectsScope no_effects(this);
8881 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE); 8896 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
8882 AddStore(receiver, 8897 AddStore(receiver,
8883 HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset), 8898 HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset),
8884 initial_map_value); 8899 initial_map_value);
8885 HValue* empty_fixed_array = 8900 HValue* empty_fixed_array =
8886 AddInstruction(new(zone()) HConstant(factory->empty_fixed_array(), 8901 AddInstruction(new(zone()) HConstant(factory->empty_fixed_array()));
8887 Representation::Tagged()));
8888 AddStore(receiver, 8902 AddStore(receiver,
8889 HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset), 8903 HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset),
8890 empty_fixed_array); 8904 empty_fixed_array);
8891 AddStore(receiver, 8905 AddStore(receiver,
8892 HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset), 8906 HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset),
8893 empty_fixed_array); 8907 empty_fixed_array);
8894 if (initial_map->inobject_properties() != 0) { 8908 if (initial_map->inobject_properties() != 0) {
8895 HConstant* undefined = graph()->GetConstantUndefined(); 8909 HConstant* undefined = graph()->GetConstantUndefined();
8896 for (int i = 0; i < initial_map->inobject_properties(); i++) { 8910 for (int i = 0; i < initial_map->inobject_properties(); i++) {
8897 int property_offset = JSObject::kHeaderSize + i * kPointerSize; 8911 int property_offset = JSObject::kHeaderSize + i * kPointerSize;
(...skipping 26 matching lines...) Expand all
8924 receiver->DeleteAndReplaceWith(NULL); 8938 receiver->DeleteAndReplaceWith(NULL);
8925 check->DeleteAndReplaceWith(NULL); 8939 check->DeleteAndReplaceWith(NULL);
8926 environment()->SetExpressionStackAt(receiver_index, function); 8940 environment()->SetExpressionStackAt(receiver_index, function);
8927 HInstruction* call = PreProcessCall( 8941 HInstruction* call = PreProcessCall(
8928 new(zone()) HCallNew(context, function, argument_count)); 8942 new(zone()) HCallNew(context, function, argument_count));
8929 call->set_position(expr->position()); 8943 call->set_position(expr->position());
8930 return ast_context()->ReturnInstruction(call, expr->id()); 8944 return ast_context()->ReturnInstruction(call, expr->id());
8931 } else { 8945 } else {
8932 // The constructor function is both an operand to the instruction and an 8946 // The constructor function is both an operand to the instruction and an
8933 // argument to the construct call. 8947 // argument to the construct call.
8948 Handle<JSFunction> array_function =
8949 Handle<JSFunction>(isolate()->global_context()->array_function(),
8950 isolate());
8934 bool use_call_new_array = FLAG_optimize_constructed_arrays && 8951 bool use_call_new_array = FLAG_optimize_constructed_arrays &&
8935 !(expr->target().is_null()) && 8952 expr->target().is_identical_to(array_function);
8936 *(expr->target()) == isolate()->global_context()->array_function();
8937 8953
8938 CHECK_ALIVE(VisitArgument(expr->expression())); 8954 CHECK_ALIVE(VisitArgument(expr->expression()));
8939 HValue* constructor = HPushArgument::cast(Top())->argument(); 8955 HValue* constructor = HPushArgument::cast(Top())->argument();
8940 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 8956 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
8941 HCallNew* call; 8957 HCallNew* call;
8942 if (use_call_new_array) { 8958 if (use_call_new_array) {
8943 Handle<JSGlobalPropertyCell> cell = expr->allocation_info_cell(); 8959 Handle<Cell> cell = expr->allocation_info_cell();
8960 AddInstruction(new(zone()) HCheckFunction(constructor, array_function));
8944 call = new(zone()) HCallNewArray(context, constructor, argument_count, 8961 call = new(zone()) HCallNewArray(context, constructor, argument_count,
8945 cell); 8962 cell);
8946 } else { 8963 } else {
8947 call = new(zone()) HCallNew(context, constructor, argument_count); 8964 call = new(zone()) HCallNew(context, constructor, argument_count);
8948 } 8965 }
8949 Drop(argument_count); 8966 Drop(argument_count);
8950 call->set_position(expr->position()); 8967 call->set_position(expr->position());
8951 return ast_context()->ReturnInstruction(call, expr->id()); 8968 return ast_context()->ReturnInstruction(call, expr->id());
8952 } 8969 }
8953 } 8970 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
9072 return ast_context()->ReturnInstruction(instr, expr->id()); 9089 return ast_context()->ReturnInstruction(instr, expr->id());
9073 } 9090 }
9074 9091
9075 9092
9076 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { 9093 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
9077 CHECK_ALIVE(VisitForValue(expr->expression())); 9094 CHECK_ALIVE(VisitForValue(expr->expression()));
9078 HValue* value = Pop(); 9095 HValue* value = Pop();
9079 HValue* context = environment()->LookupContext(); 9096 HValue* context = environment()->LookupContext();
9080 HInstruction* instr = 9097 HInstruction* instr =
9081 HMul::New(zone(), context, value, graph()->GetConstantMinus1()); 9098 HMul::New(zone(), context, value, graph()->GetConstantMinus1());
9082 TypeInfo info = expr->type(); 9099 Handle<Type> type = expr->type();
9083 Representation rep = ToRepresentation(info); 9100 Representation rep = ToRepresentation(type);
9084 if (info.IsUninitialized()) { 9101 if (type->Is(Type::None())) {
9085 AddSoftDeoptimize(); 9102 AddSoftDeoptimize();
9086 info = TypeInfo::Unknown(); 9103 type = handle(Type::Any(), isolate());
9087 } 9104 }
9088 if (instr->IsBinaryOperation()) { 9105 if (instr->IsBinaryOperation()) {
9089 HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep); 9106 HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep);
9090 HBinaryOperation::cast(instr)->set_observed_input_representation(2, rep); 9107 HBinaryOperation::cast(instr)->set_observed_input_representation(2, rep);
9091 } 9108 }
9092 return ast_context()->ReturnInstruction(instr, expr->id()); 9109 return ast_context()->ReturnInstruction(instr, expr->id());
9093 } 9110 }
9094 9111
9095 9112
9096 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { 9113 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) {
9097 CHECK_ALIVE(VisitForValue(expr->expression())); 9114 CHECK_ALIVE(VisitForValue(expr->expression()));
9098 HValue* value = Pop(); 9115 HValue* value = Pop();
9099 TypeInfo info = expr->type(); 9116 Handle<Type> info = expr->type();
9100 if (info.IsUninitialized()) { 9117 if (info->Is(Type::None())) {
9101 AddSoftDeoptimize(); 9118 AddSoftDeoptimize();
9102 } 9119 }
9103 HInstruction* instr = new(zone()) HBitNot(value); 9120 HInstruction* instr = new(zone()) HBitNot(value);
9104 return ast_context()->ReturnInstruction(instr, expr->id()); 9121 return ast_context()->ReturnInstruction(instr, expr->id());
9105 } 9122 }
9106 9123
9107 9124
9108 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { 9125 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) {
9109 if (ast_context()->IsTest()) { 9126 if (ast_context()->IsTest()) {
9110 TestContext* context = TestContext::cast(ast_context()); 9127 TestContext* context = TestContext::cast(ast_context());
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
9270 9287
9271 if (prop->key()->IsPropertyName()) { 9288 if (prop->key()->IsPropertyName()) {
9272 // Named property. 9289 // Named property.
9273 if (returns_original_input) Push(graph()->GetConstantUndefined()); 9290 if (returns_original_input) Push(graph()->GetConstantUndefined());
9274 9291
9275 CHECK_ALIVE(VisitForValue(prop->obj())); 9292 CHECK_ALIVE(VisitForValue(prop->obj()));
9276 HValue* object = Top(); 9293 HValue* object = Top();
9277 9294
9278 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 9295 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
9279 Handle<Map> map; 9296 Handle<Map> map;
9280 HInstruction* load; 9297 HInstruction* load = NULL;
9281 bool monomorphic = prop->IsMonomorphic(); 9298 bool monomorphic = prop->IsMonomorphic();
9299 SmallMapList* types = prop->GetReceiverTypes();
9282 if (monomorphic) { 9300 if (monomorphic) {
9283 map = prop->GetReceiverTypes()->first(); 9301 map = types->first();
9284 if (map->is_dictionary_map()) monomorphic = false; 9302 if (map->is_dictionary_map()) monomorphic = false;
9285 } 9303 }
9286 if (monomorphic) { 9304 if (monomorphic) {
9287 Handle<JSFunction> getter; 9305 Handle<JSFunction> getter;
9288 Handle<JSObject> holder; 9306 Handle<JSObject> holder;
9289 if (LookupGetter(map, name, &getter, &holder)) { 9307 if (LookupGetter(map, name, &getter, &holder)) {
9290 load = BuildCallGetter(object, map, getter, holder); 9308 load = BuildCallGetter(object, map, getter, holder);
9291 } else { 9309 } else {
9292 load = BuildLoadNamedMonomorphic(object, name, prop, map); 9310 load = BuildLoadNamedMonomorphic(object, name, prop, map);
9293 } 9311 }
9294 } else { 9312 } else if (types != NULL && types->length() > 1) {
9295 load = BuildLoadNamedGeneric(object, name, prop); 9313 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
9296 } 9314 }
9315 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
9297 PushAndAdd(load); 9316 PushAndAdd(load);
9298 if (load->HasObservableSideEffects()) { 9317 if (load->HasObservableSideEffects()) {
9299 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 9318 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
9300 } 9319 }
9301 9320
9302 after = BuildIncrement(returns_original_input, expr); 9321 after = BuildIncrement(returns_original_input, expr);
9303 input = Pop(); 9322 input = Pop();
9304 9323
9305 HInstruction* store; 9324 HInstruction* store;
9306 if (!monomorphic || map->is_observed()) { 9325 if (!monomorphic || map->is_observed()) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
9374 HValue* context, 9393 HValue* context,
9375 HValue* string, 9394 HValue* string,
9376 HValue* index) { 9395 HValue* index) {
9377 if (string->IsConstant() && index->IsConstant()) { 9396 if (string->IsConstant() && index->IsConstant()) {
9378 HConstant* c_string = HConstant::cast(string); 9397 HConstant* c_string = HConstant::cast(string);
9379 HConstant* c_index = HConstant::cast(index); 9398 HConstant* c_index = HConstant::cast(index);
9380 if (c_string->HasStringValue() && c_index->HasNumberValue()) { 9399 if (c_string->HasStringValue() && c_index->HasNumberValue()) {
9381 int32_t i = c_index->NumberValueAsInteger32(); 9400 int32_t i = c_index->NumberValueAsInteger32();
9382 Handle<String> s = c_string->StringValue(); 9401 Handle<String> s = c_string->StringValue();
9383 if (i < 0 || i >= s->length()) { 9402 if (i < 0 || i >= s->length()) {
9384 return new(zone()) HConstant(OS::nan_value(), Representation::Double()); 9403 return new(zone()) HConstant(OS::nan_value());
9385 } 9404 }
9386 return new(zone()) HConstant(s->Get(i)); 9405 return new(zone()) HConstant(s->Get(i));
9387 } 9406 }
9388 } 9407 }
9389 BuildCheckNonSmi(string); 9408 BuildCheckNonSmi(string);
9390 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 9409 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
9391 HInstruction* length = HStringLength::New(zone(), string); 9410 HInstruction* length = HStringLength::New(zone(), string);
9392 AddInstruction(length); 9411 AddInstruction(length);
9393 HInstruction* checked_index = AddBoundsCheck(index, length); 9412 HInstruction* checked_index = AddBoundsCheck(index, length);
9394 return new(zone()) HStringCharCodeAt(context, string, checked_index); 9413 return new(zone()) HStringCharCodeAt(context, string, checked_index);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
9450 } 9469 }
9451 return true; 9470 return true;
9452 } 9471 }
9453 9472
9454 9473
9455 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( 9474 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
9456 BinaryOperation* expr, 9475 BinaryOperation* expr,
9457 HValue* left, 9476 HValue* left,
9458 HValue* right) { 9477 HValue* right) {
9459 HValue* context = environment()->LookupContext(); 9478 HValue* context = environment()->LookupContext();
9460 TypeInfo left_info = expr->left_type(); 9479 Handle<Type> left_type = expr->left_type();
9461 TypeInfo right_info = expr->right_type(); 9480 Handle<Type> right_type = expr->right_type();
9462 TypeInfo result_info = expr->result_type(); 9481 Handle<Type> result_type = expr->result_type();
9463 bool has_fixed_right_arg = expr->has_fixed_right_arg(); 9482 bool has_fixed_right_arg = expr->has_fixed_right_arg();
9464 int fixed_right_arg_value = expr->fixed_right_arg_value(); 9483 int fixed_right_arg_value = expr->fixed_right_arg_value();
9465 Representation left_rep = ToRepresentation(left_info); 9484 Representation left_rep = ToRepresentation(left_type);
9466 Representation right_rep = ToRepresentation(right_info); 9485 Representation right_rep = ToRepresentation(right_type);
9467 Representation result_rep = ToRepresentation(result_info); 9486 Representation result_rep = ToRepresentation(result_type);
9468 if (left_info.IsUninitialized()) { 9487 if (left_type->Is(Type::None())) {
9469 // Can't have initialized one but not the other.
9470 ASSERT(right_info.IsUninitialized());
9471 AddSoftDeoptimize(); 9488 AddSoftDeoptimize();
9472 left_info = right_info = TypeInfo::Unknown(); 9489 left_type = handle(Type::Any(), isolate());
9490 }
9491 if (right_type->Is(Type::None())) {
9492 AddSoftDeoptimize();
9493 right_type = handle(Type::Any(), isolate());
9473 } 9494 }
9474 HInstruction* instr = NULL; 9495 HInstruction* instr = NULL;
9475 switch (expr->op()) { 9496 switch (expr->op()) {
9476 case Token::ADD: 9497 case Token::ADD:
9477 if (left_info.IsString() && right_info.IsString()) { 9498 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) {
9478 BuildCheckNonSmi(left); 9499 BuildCheckNonSmi(left);
9479 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); 9500 AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
9480 BuildCheckNonSmi(right); 9501 BuildCheckNonSmi(right);
9481 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); 9502 AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
9482 instr = HStringAdd::New(zone(), context, left, right); 9503 instr = HStringAdd::New(zone(), context, left, right);
9483 } else { 9504 } else {
9484 instr = HAdd::New(zone(), context, left, right); 9505 instr = HAdd::New(zone(), context, left, right);
9485 } 9506 }
9486 break; 9507 break;
9487 case Token::SUB: 9508 case Token::SUB:
(...skipping 12 matching lines...) Expand all
9500 break; 9521 break;
9501 case Token::DIV: 9522 case Token::DIV:
9502 instr = HDiv::New(zone(), context, left, right); 9523 instr = HDiv::New(zone(), context, left, right);
9503 break; 9524 break;
9504 case Token::BIT_XOR: 9525 case Token::BIT_XOR:
9505 case Token::BIT_AND: 9526 case Token::BIT_AND:
9506 instr = HBitwise::New(zone(), expr->op(), context, left, right); 9527 instr = HBitwise::New(zone(), expr->op(), context, left, right);
9507 break; 9528 break;
9508 case Token::BIT_OR: { 9529 case Token::BIT_OR: {
9509 HValue* operand, *shift_amount; 9530 HValue* operand, *shift_amount;
9510 if (left_info.IsInteger32() && right_info.IsInteger32() && 9531 if (left_type->Is(Type::Integer32()) &&
9532 right_type->Is(Type::Integer32()) &&
9511 MatchRotateRight(left, right, &operand, &shift_amount)) { 9533 MatchRotateRight(left, right, &operand, &shift_amount)) {
9512 instr = new(zone()) HRor(context, operand, shift_amount); 9534 instr = new(zone()) HRor(context, operand, shift_amount);
9513 } else { 9535 } else {
9514 instr = HBitwise::New(zone(), expr->op(), context, left, right); 9536 instr = HBitwise::New(zone(), expr->op(), context, left, right);
9515 } 9537 }
9516 break; 9538 break;
9517 } 9539 }
9518 case Token::SAR: 9540 case Token::SAR:
9519 instr = HSar::New(zone(), context, left, right); 9541 instr = HSar::New(zone(), context, left, right);
9520 break; 9542 break;
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
9686 CHECK_ALIVE(VisitForValue(expr->left())); 9708 CHECK_ALIVE(VisitForValue(expr->left()));
9687 CHECK_ALIVE(VisitForValue(expr->right())); 9709 CHECK_ALIVE(VisitForValue(expr->right()));
9688 HValue* right = Pop(); 9710 HValue* right = Pop();
9689 HValue* left = Pop(); 9711 HValue* left = Pop();
9690 HInstruction* instr = BuildBinaryOperation(expr, left, right); 9712 HInstruction* instr = BuildBinaryOperation(expr, left, right);
9691 instr->set_position(expr->position()); 9713 instr->set_position(expr->position());
9692 return ast_context()->ReturnInstruction(instr, expr->id()); 9714 return ast_context()->ReturnInstruction(instr, expr->id());
9693 } 9715 }
9694 9716
9695 9717
9718 // TODO(rossberg): this should die eventually.
9696 Representation HOptimizedGraphBuilder::ToRepresentation(TypeInfo info) { 9719 Representation HOptimizedGraphBuilder::ToRepresentation(TypeInfo info) {
9697 if (info.IsUninitialized()) return Representation::None(); 9720 if (info.IsUninitialized()) return Representation::None();
9721 // TODO(verwaest): Return Smi rather than Integer32.
9698 if (info.IsSmi()) return Representation::Integer32(); 9722 if (info.IsSmi()) return Representation::Integer32();
9699 if (info.IsInteger32()) return Representation::Integer32(); 9723 if (info.IsInteger32()) return Representation::Integer32();
9700 if (info.IsDouble()) return Representation::Double(); 9724 if (info.IsDouble()) return Representation::Double();
9701 if (info.IsNumber()) return Representation::Double(); 9725 if (info.IsNumber()) return Representation::Double();
9702 return Representation::Tagged(); 9726 return Representation::Tagged();
9703 } 9727 }
9704 9728
9705 9729
9730 Representation HOptimizedGraphBuilder::ToRepresentation(Handle<Type> type) {
9731 if (type->Is(Type::None())) return Representation::None();
9732 if (type->Is(Type::Integer32())) return Representation::Integer32();
9733 if (type->Is(Type::Number())) return Representation::Double();
9734 return Representation::Tagged();
9735 }
9736
9737
9706 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 9738 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
9707 HTypeof* typeof_expr, 9739 HTypeof* typeof_expr,
9708 Handle<String> check) { 9740 Handle<String> check) {
9709 // Note: The HTypeof itself is removed during canonicalization, if possible. 9741 // Note: The HTypeof itself is removed during canonicalization, if possible.
9710 HValue* value = typeof_expr->value(); 9742 HValue* value = typeof_expr->value();
9711 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); 9743 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check);
9712 instr->set_position(expr->position()); 9744 instr->set_position(expr->position());
9713 return ast_context()->ReturnControl(instr, expr->id()); 9745 return ast_context()->ReturnControl(instr, expr->id());
9714 } 9746 }
9715 9747
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
9785 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9817 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9786 HValue* value = Pop(); 9818 HValue* value = Pop();
9787 Literal* literal = expr->right()->AsLiteral(); 9819 Literal* literal = expr->right()->AsLiteral();
9788 Handle<String> rhs = Handle<String>::cast(literal->handle()); 9820 Handle<String> rhs = Handle<String>::cast(literal->handle());
9789 HClassOfTestAndBranch* instr = 9821 HClassOfTestAndBranch* instr =
9790 new(zone()) HClassOfTestAndBranch(value, rhs); 9822 new(zone()) HClassOfTestAndBranch(value, rhs);
9791 instr->set_position(expr->position()); 9823 instr->set_position(expr->position());
9792 return ast_context()->ReturnControl(instr, expr->id()); 9824 return ast_context()->ReturnControl(instr, expr->id());
9793 } 9825 }
9794 9826
9795 TypeInfo left_type = expr->left_type(); 9827 Handle<Type> left_type = expr->left_type();
9796 TypeInfo right_type = expr->right_type(); 9828 Handle<Type> right_type = expr->right_type();
9797 TypeInfo overall_type = expr->overall_type(); 9829 Handle<Type> overall_type = expr->overall_type();
9798 Representation combined_rep = ToRepresentation(overall_type); 9830 Representation combined_rep = ToRepresentation(overall_type);
9799 Representation left_rep = ToRepresentation(left_type); 9831 Representation left_rep = ToRepresentation(left_type);
9800 Representation right_rep = ToRepresentation(right_type); 9832 Representation right_rep = ToRepresentation(right_type);
9801 // Check if this expression was ever executed according to type feedback. 9833 // Check if this expression was ever executed according to type feedback.
9802 // Note that for the special typeof/null/undefined cases we get unknown here. 9834 // Note that for the special typeof/null/undefined cases we get unknown here.
9803 if (overall_type.IsUninitialized()) { 9835 if (overall_type->Is(Type::None())) {
9804 AddSoftDeoptimize(); 9836 AddSoftDeoptimize();
9805 overall_type = left_type = right_type = TypeInfo::Unknown(); 9837 overall_type = left_type = right_type = handle(Type::Any(), isolate());
9806 } 9838 }
9807 9839
9808 CHECK_ALIVE(VisitForValue(expr->left())); 9840 CHECK_ALIVE(VisitForValue(expr->left()));
9809 CHECK_ALIVE(VisitForValue(expr->right())); 9841 CHECK_ALIVE(VisitForValue(expr->right()));
9810 9842
9811 HValue* context = environment()->LookupContext(); 9843 HValue* context = environment()->LookupContext();
9812 HValue* right = Pop(); 9844 HValue* right = Pop();
9813 HValue* left = Pop(); 9845 HValue* left = Pop();
9814 Token::Value op = expr->op(); 9846 Token::Value op = expr->op();
9815 9847
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
9867 AddInstruction(new(zone()) HCheckFunction(right, target)); 9899 AddInstruction(new(zone()) HCheckFunction(right, target));
9868 HInstanceOfKnownGlobal* result = 9900 HInstanceOfKnownGlobal* result =
9869 new(zone()) HInstanceOfKnownGlobal(context, left, target); 9901 new(zone()) HInstanceOfKnownGlobal(context, left, target);
9870 result->set_position(expr->position()); 9902 result->set_position(expr->position());
9871 return ast_context()->ReturnInstruction(result, expr->id()); 9903 return ast_context()->ReturnInstruction(result, expr->id());
9872 } 9904 }
9873 } else if (op == Token::IN) { 9905 } else if (op == Token::IN) {
9874 HIn* result = new(zone()) HIn(context, left, right); 9906 HIn* result = new(zone()) HIn(context, left, right);
9875 result->set_position(expr->position()); 9907 result->set_position(expr->position());
9876 return ast_context()->ReturnInstruction(result, expr->id()); 9908 return ast_context()->ReturnInstruction(result, expr->id());
9877 } else if (overall_type.IsNonPrimitive()) { 9909 } else if (overall_type->Is(Type::Receiver())) {
9878 switch (op) { 9910 switch (op) {
9879 case Token::EQ: 9911 case Token::EQ:
9880 case Token::EQ_STRICT: { 9912 case Token::EQ_STRICT: {
9881 // Can we get away with map check and not instance type check? 9913 // Can we get away with map check and not instance type check?
9882 Handle<Map> map = expr->map(); 9914 if (overall_type->IsClass()) {
9883 if (!map.is_null()) { 9915 Handle<Map> map = overall_type->AsClass();
9884 AddCheckMapsWithTransitions(left, map); 9916 AddCheckMapsWithTransitions(left, map);
9885 AddCheckMapsWithTransitions(right, map); 9917 AddCheckMapsWithTransitions(right, map);
9886 HCompareObjectEqAndBranch* result = 9918 HCompareObjectEqAndBranch* result =
9887 new(zone()) HCompareObjectEqAndBranch(left, right); 9919 new(zone()) HCompareObjectEqAndBranch(left, right);
9888 result->set_position(expr->position()); 9920 result->set_position(expr->position());
9889 return ast_context()->ReturnControl(result, expr->id()); 9921 return ast_context()->ReturnControl(result, expr->id());
9890 } else { 9922 } else {
9891 BuildCheckNonSmi(left); 9923 BuildCheckNonSmi(left);
9892 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); 9924 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone()));
9893 BuildCheckNonSmi(right); 9925 BuildCheckNonSmi(right);
9894 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); 9926 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone()));
9895 HCompareObjectEqAndBranch* result = 9927 HCompareObjectEqAndBranch* result =
9896 new(zone()) HCompareObjectEqAndBranch(left, right); 9928 new(zone()) HCompareObjectEqAndBranch(left, right);
9897 result->set_position(expr->position()); 9929 result->set_position(expr->position());
9898 return ast_context()->ReturnControl(result, expr->id()); 9930 return ast_context()->ReturnControl(result, expr->id());
9899 } 9931 }
9900 } 9932 }
9901 default: 9933 default:
9902 return Bailout("Unsupported non-primitive compare"); 9934 return Bailout("Unsupported non-primitive compare");
9903 } 9935 }
9904 } else if (overall_type.IsInternalizedString() && 9936 } else if (overall_type->Is(Type::InternalizedString()) &&
9905 Token::IsEqualityOp(op)) { 9937 Token::IsEqualityOp(op)) {
9906 BuildCheckNonSmi(left); 9938 BuildCheckNonSmi(left);
9907 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); 9939 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone()));
9908 BuildCheckNonSmi(right); 9940 BuildCheckNonSmi(right);
9909 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); 9941 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone()));
9910 HCompareObjectEqAndBranch* result = 9942 HCompareObjectEqAndBranch* result =
9911 new(zone()) HCompareObjectEqAndBranch(left, right); 9943 new(zone()) HCompareObjectEqAndBranch(left, right);
9912 result->set_position(expr->position()); 9944 result->set_position(expr->position());
9913 return ast_context()->ReturnControl(result, expr->id()); 9945 return ast_context()->ReturnControl(result, expr->id());
9914 } else { 9946 } else {
9915 if (combined_rep.IsTagged() || combined_rep.IsNone()) { 9947 if (combined_rep.IsTagged() || combined_rep.IsNone()) {
9916 HCompareGeneric* result = 9948 HCompareGeneric* result =
9917 new(zone()) HCompareGeneric(context, left, right, op); 9949 new(zone()) HCompareGeneric(context, left, right, op);
9918 result->set_observed_input_representation(1, left_rep); 9950 result->set_observed_input_representation(1, left_rep);
9919 result->set_observed_input_representation(2, right_rep); 9951 result->set_observed_input_representation(2, right_rep);
9920 result->set_position(expr->position()); 9952 result->set_position(expr->position());
9921 return ast_context()->ReturnInstruction(result, expr->id()); 9953 return ast_context()->ReturnInstruction(result, expr->id());
9922 } else { 9954 } else {
9955 // TODO(verwaest): Remove once ToRepresentation properly returns Smi when
9956 // the IC measures Smi.
9957 if (left_type->Is(Type::Integer31())) left_rep = Representation::Smi();
9958 if (right_type->Is(Type::Integer31())) right_rep = Representation::Smi();
9923 HCompareIDAndBranch* result = 9959 HCompareIDAndBranch* result =
9924 new(zone()) HCompareIDAndBranch(left, right, op); 9960 new(zone()) HCompareIDAndBranch(left, right, op);
9925 result->set_observed_input_representation(left_rep, right_rep); 9961 result->set_observed_input_representation(left_rep, right_rep);
9926 result->set_position(expr->position()); 9962 result->set_position(expr->position());
9927 return ast_context()->ReturnControl(result, expr->id()); 9963 return ast_context()->ReturnControl(result, expr->id());
9928 } 9964 }
9929 } 9965 }
9930 } 9966 }
9931 9967
9932 9968
9933 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 9969 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
9934 HValue* value, 9970 HValue* value,
9935 NilValue nil) { 9971 NilValue nil) {
9936 ASSERT(!HasStackOverflow()); 9972 ASSERT(!HasStackOverflow());
9937 ASSERT(current_block() != NULL); 9973 ASSERT(current_block() != NULL);
9938 ASSERT(current_block()->HasPredecessor()); 9974 ASSERT(current_block()->HasPredecessor());
9975 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT);
9939 HIfContinuation continuation; 9976 HIfContinuation continuation;
9940 CompareNilICStub::Types types;
9941 if (expr->op() == Token::EQ_STRICT) { 9977 if (expr->op() == Token::EQ_STRICT) {
9942 IfBuilder if_nil(this); 9978 IfBuilder if_nil(this);
9943 if_nil.If<HCompareObjectEqAndBranch>( 9979 if_nil.If<HCompareObjectEqAndBranch>(
9944 value, (nil == kNullValue) ? graph()->GetConstantNull() 9980 value, (nil == kNullValue) ? graph()->GetConstantNull()
9945 : graph()->GetConstantUndefined()); 9981 : graph()->GetConstantUndefined());
9946 if_nil.Then(); 9982 if_nil.Then();
9947 if_nil.Else(); 9983 if_nil.Else();
9948 if_nil.CaptureContinuation(&continuation); 9984 if_nil.CaptureContinuation(&continuation);
9949 return ast_context()->ReturnContinuation(&continuation, expr->id()); 9985 return ast_context()->ReturnContinuation(&continuation, expr->id());
9950 } 9986 }
9951 types = CompareNilICStub::Types(expr->compare_nil_types()); 9987 Handle<Type> type = expr->compare_nil_type()->Is(Type::None())
9952 if (types.IsEmpty()) types = CompareNilICStub::Types::FullCompare(); 9988 ? handle(Type::Any(), isolate_) : expr->compare_nil_type();
9953 Handle<Map> map_handle = expr->map(); 9989 BuildCompareNil(value, type, expr->position(), &continuation);
9954 BuildCompareNil(value, types, map_handle,
9955 expr->position(), &continuation);
9956 return ast_context()->ReturnContinuation(&continuation, expr->id()); 9990 return ast_context()->ReturnContinuation(&continuation, expr->id());
9957 } 9991 }
9958 9992
9959 9993
9960 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 9994 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
9961 // If we share optimized code between different closures, the 9995 // If we share optimized code between different closures, the
9962 // this-function is not a constant, except inside an inlined body. 9996 // this-function is not a constant, except inside an inlined body.
9963 if (function_state()->outer() != NULL) { 9997 if (function_state()->outer() != NULL) {
9964 return new(zone()) HConstant( 9998 return new(zone()) HConstant(
9965 function_state()->compilation_info()->closure(), 9999 function_state()->compilation_info()->closure());
9966 Representation::Tagged());
9967 } else { 10000 } else {
9968 return new(zone()) HThisFunction; 10001 return new(zone()) HThisFunction;
9969 } 10002 }
9970 } 10003 }
9971 10004
9972 10005
9973 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 10006 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
9974 HValue* context, 10007 HValue* context,
9975 Handle<JSObject> boilerplate_object, 10008 Handle<JSObject> boilerplate_object,
9976 Handle<JSObject> original_boilerplate_object, 10009 Handle<JSObject> original_boilerplate_object,
9977 int data_size, 10010 int data_size,
9978 int pointer_size, 10011 int pointer_size,
9979 AllocationSiteMode mode) { 10012 AllocationSiteMode mode) {
9980 Zone* zone = this->zone(); 10013 Zone* zone = this->zone();
9981 int total_size = data_size + pointer_size; 10014 int total_size = data_size + pointer_size;
9982 10015
9983 NoObservableSideEffectsScope no_effects(this); 10016 NoObservableSideEffectsScope no_effects(this);
9984 10017
9985 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; 10018 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE;
9986 // TODO(hpayer): add support for old data space 10019 // TODO(hpayer): add support for old data space
9987 if (isolate()->heap()->ShouldGloballyPretenure() && 10020 if (isolate()->heap()->ShouldGloballyPretenure() &&
9988 data_size == 0) { 10021 data_size == 0) {
9989 flags = static_cast<HAllocate::Flags>( 10022 flags = static_cast<HAllocate::Flags>(
9990 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 10023 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
9991 } 10024 }
9992 10025
9993 HValue* size_in_bytes = 10026 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(total_size));
9994 AddInstruction(new(zone) HConstant(total_size,
9995 Representation::Integer32()));
9996 HInstruction* result = 10027 HInstruction* result =
9997 AddInstruction(new(zone) HAllocate(context, 10028 AddInstruction(new(zone) HAllocate(context,
9998 size_in_bytes, 10029 size_in_bytes,
9999 HType::JSObject(), 10030 HType::JSObject(),
10000 flags)); 10031 flags));
10001 int offset = 0; 10032 int offset = 0;
10002 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, result, 10033 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, result,
10003 &offset, mode); 10034 &offset, mode);
10004 return result; 10035 return result;
10005 } 10036 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
10042 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); 10073 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset));
10043 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, 10074 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object,
10044 object_properties, target, offset); 10075 object_properties, target, offset);
10045 10076
10046 // Create allocation site info. 10077 // Create allocation site info.
10047 if (mode == TRACK_ALLOCATION_SITE && 10078 if (mode == TRACK_ALLOCATION_SITE &&
10048 boilerplate_object->map()->CanTrackAllocationSite()) { 10079 boilerplate_object->map()->CanTrackAllocationSite()) {
10049 elements_offset += AllocationSiteInfo::kSize; 10080 elements_offset += AllocationSiteInfo::kSize;
10050 *offset += AllocationSiteInfo::kSize; 10081 *offset += AllocationSiteInfo::kSize;
10051 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( 10082 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant(
10052 original_boilerplate_object, Representation::Tagged())); 10083 original_boilerplate_object));
10053 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); 10084 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate);
10054 } 10085 }
10055 } 10086 }
10056 10087
10057 10088
10058 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader( 10089 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader(
10059 Handle<JSObject> boilerplate_object, 10090 Handle<JSObject> boilerplate_object,
10060 HInstruction* target, 10091 HInstruction* target,
10061 int object_offset, 10092 int object_offset,
10062 int elements_offset, 10093 int elements_offset,
10063 int elements_size) { 10094 int elements_size) {
10064 ASSERT(boilerplate_object->properties()->length() == 0); 10095 ASSERT(boilerplate_object->properties()->length() == 0);
10065 Zone* zone = this->zone(); 10096 Zone* zone = this->zone();
10066 HValue* result = NULL; 10097 HValue* result = NULL;
10067 10098
10068 HValue* object_header = 10099 HValue* object_header =
10069 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); 10100 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset));
10070 Handle<Map> boilerplate_object_map(boilerplate_object->map()); 10101 Handle<Map> boilerplate_object_map(boilerplate_object->map());
10071 AddStoreMapConstant(object_header, boilerplate_object_map); 10102 AddStoreMapConstant(object_header, boilerplate_object_map);
10072 10103
10073 HInstruction* elements; 10104 HInstruction* elements;
10074 if (elements_size == 0) { 10105 if (elements_size == 0) {
10075 Handle<Object> elements_field = 10106 Handle<Object> elements_field =
10076 Handle<Object>(boilerplate_object->elements(), isolate()); 10107 Handle<Object>(boilerplate_object->elements(), isolate());
10077 elements = AddInstruction(new(zone) HConstant( 10108 elements = AddInstruction(new(zone) HConstant(elements_field));
10078 elements_field, Representation::Tagged()));
10079 } else { 10109 } else {
10080 elements = AddInstruction(new(zone) HInnerAllocatedObject( 10110 elements = AddInstruction(new(zone) HInnerAllocatedObject(
10081 target, elements_offset)); 10111 target, elements_offset));
10082 result = elements; 10112 result = elements;
10083 } 10113 }
10084 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); 10114 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements);
10085 10115
10086 Handle<Object> properties_field = 10116 Handle<Object> properties_field =
10087 Handle<Object>(boilerplate_object->properties(), isolate()); 10117 Handle<Object>(boilerplate_object->properties(), isolate());
10088 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 10118 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
10089 HInstruction* properties = AddInstruction(new(zone) HConstant( 10119 HInstruction* properties = AddInstruction(new(zone) HConstant(
10090 properties_field, Representation::None())); 10120 properties_field));
10091 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 10121 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
10092 AddStore(object_header, access, properties); 10122 AddStore(object_header, access, properties);
10093 10123
10094 if (boilerplate_object->IsJSArray()) { 10124 if (boilerplate_object->IsJSArray()) {
10095 Handle<JSArray> boilerplate_array = 10125 Handle<JSArray> boilerplate_array =
10096 Handle<JSArray>::cast(boilerplate_object); 10126 Handle<JSArray>::cast(boilerplate_object);
10097 Handle<Object> length_field = 10127 Handle<Object> length_field =
10098 Handle<Object>(boilerplate_array->length(), isolate()); 10128 Handle<Object>(boilerplate_array->length(), isolate());
10099 HInstruction* length = AddInstruction(new(zone) HConstant( 10129 HInstruction* length = AddInstruction(new(zone) HConstant(length_field));
10100 length_field, Representation::None()));
10101 10130
10102 ASSERT(boilerplate_array->length()->IsSmi()); 10131 ASSERT(boilerplate_array->length()->IsSmi());
10103 Representation representation = 10132 Representation representation =
10104 IsFastElementsKind(boilerplate_array->GetElementsKind()) 10133 IsFastElementsKind(boilerplate_array->GetElementsKind())
10105 ? Representation::Smi() : Representation::Tagged(); 10134 ? Representation::Smi() : Representation::Tagged();
10106 AddStore(object_header, HObjectAccess::ForArrayLength(), 10135 AddStore(object_header, HObjectAccess::ForArrayLength(),
10107 length, representation); 10136 length, representation);
10108 } 10137 }
10109 10138
10110 return result; 10139 return result;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
10146 isolate())); 10175 isolate()));
10147 HInstruction* value_instruction = 10176 HInstruction* value_instruction =
10148 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); 10177 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset));
10149 10178
10150 AddStore(object_properties, access, value_instruction); 10179 AddStore(object_properties, access, value_instruction);
10151 10180
10152 BuildEmitDeepCopy(value_object, original_value_object, target, 10181 BuildEmitDeepCopy(value_object, original_value_object, target,
10153 offset, DONT_TRACK_ALLOCATION_SITE); 10182 offset, DONT_TRACK_ALLOCATION_SITE);
10154 } else { 10183 } else {
10155 Representation representation = details.representation(); 10184 Representation representation = details.representation();
10156 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( 10185 HInstruction* value_instruction =
10157 value, Representation::Tagged())); 10186 AddInstruction(new(zone) HConstant(value));
10158 10187
10159 if (representation.IsDouble()) { 10188 if (representation.IsDouble()) {
10160 // Allocate a HeapNumber box and store the value into it. 10189 // Allocate a HeapNumber box and store the value into it.
10161 HInstruction* double_box = 10190 HInstruction* double_box =
10162 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); 10191 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset));
10163 AddStoreMapConstant(double_box, 10192 AddStoreMapConstant(double_box,
10164 isolate()->factory()->heap_number_map()); 10193 isolate()->factory()->heap_number_map());
10165 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 10194 AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
10166 value_instruction, Representation::Double()); 10195 value_instruction, Representation::Double());
10167 value_instruction = double_box; 10196 value_instruction = double_box;
10168 *offset += HeapNumber::kSize; 10197 *offset += HeapNumber::kSize;
10169 } 10198 }
10170 10199
10171 AddStore(object_properties, access, value_instruction); 10200 AddStore(object_properties, access, value_instruction);
10172 } 10201 }
10173 } 10202 }
10174 10203
10175 int inobject_properties = boilerplate_object->map()->inobject_properties(); 10204 int inobject_properties = boilerplate_object->map()->inobject_properties();
10176 HInstruction* value_instruction = AddInstruction(new(zone) 10205 HInstruction* value_instruction = AddInstruction(new(zone)
10177 HConstant(isolate()->factory()->one_pointer_filler_map(), 10206 HConstant(isolate()->factory()->one_pointer_filler_map()));
10178 Representation::Tagged()));
10179 for (int i = copied_fields; i < inobject_properties; i++) { 10207 for (int i = copied_fields; i < inobject_properties; i++) {
10180 ASSERT(boilerplate_object->IsJSObject()); 10208 ASSERT(boilerplate_object->IsJSObject());
10181 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); 10209 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
10182 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); 10210 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset);
10183 AddStore(object_properties, access, value_instruction); 10211 AddStore(object_properties, access, value_instruction);
10184 } 10212 }
10185 } 10213 }
10186 10214
10187 10215
10188 void HOptimizedGraphBuilder::BuildEmitElements( 10216 void HOptimizedGraphBuilder::BuildEmitElements(
(...skipping 21 matching lines...) Expand all
10210 UNREACHABLE(); 10238 UNREACHABLE();
10211 } 10239 }
10212 } 10240 }
10213 10241
10214 10242
10215 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( 10243 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray(
10216 Handle<FixedArrayBase> elements, 10244 Handle<FixedArrayBase> elements,
10217 ElementsKind kind, 10245 ElementsKind kind,
10218 HValue* object_elements) { 10246 HValue* object_elements) {
10219 Zone* zone = this->zone(); 10247 Zone* zone = this->zone();
10220 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( 10248 HInstruction* boilerplate_elements =
10221 elements, Representation::Tagged())); 10249 AddInstruction(new(zone) HConstant(elements));
10222 int elements_length = elements->length(); 10250 int elements_length = elements->length();
10223 for (int i = 0; i < elements_length; i++) { 10251 for (int i = 0; i < elements_length; i++) {
10224 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); 10252 HValue* key_constant = AddInstruction(new(zone) HConstant(i));
10225 HInstruction* value_instruction = 10253 HInstruction* value_instruction =
10226 AddInstruction(new(zone) HLoadKeyed( 10254 AddInstruction(new(zone) HLoadKeyed(
10227 boilerplate_elements, key_constant, NULL, kind, ALLOW_RETURN_HOLE)); 10255 boilerplate_elements, key_constant, NULL, kind, ALLOW_RETURN_HOLE));
10228 HInstruction* store = AddInstruction(new(zone) HStoreKeyed( 10256 HInstruction* store = AddInstruction(new(zone) HStoreKeyed(
10229 object_elements, key_constant, value_instruction, kind)); 10257 object_elements, key_constant, value_instruction, kind));
10230 store->SetFlag(HValue::kAllowUndefinedAsNaN); 10258 store->SetFlag(HValue::kAllowUndefinedAsNaN);
10231 } 10259 }
10232 } 10260 }
10233 10261
10234 10262
10235 void HOptimizedGraphBuilder::BuildEmitFixedArray( 10263 void HOptimizedGraphBuilder::BuildEmitFixedArray(
10236 Handle<FixedArrayBase> elements, 10264 Handle<FixedArrayBase> elements,
10237 Handle<FixedArrayBase> original_elements, 10265 Handle<FixedArrayBase> original_elements,
10238 ElementsKind kind, 10266 ElementsKind kind,
10239 HValue* object_elements, 10267 HValue* object_elements,
10240 HInstruction* target, 10268 HInstruction* target,
10241 int* offset) { 10269 int* offset) {
10242 Zone* zone = this->zone(); 10270 Zone* zone = this->zone();
10243 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( 10271 HInstruction* boilerplate_elements =
10244 elements, Representation::Tagged())); 10272 AddInstruction(new(zone) HConstant(elements));
10245 int elements_length = elements->length(); 10273 int elements_length = elements->length();
10246 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 10274 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
10247 Handle<FixedArray> original_fast_elements = 10275 Handle<FixedArray> original_fast_elements =
10248 Handle<FixedArray>::cast(original_elements); 10276 Handle<FixedArray>::cast(original_elements);
10249 for (int i = 0; i < elements_length; i++) { 10277 for (int i = 0; i < elements_length; i++) {
10250 Handle<Object> value(fast_elements->get(i), isolate()); 10278 Handle<Object> value(fast_elements->get(i), isolate());
10251 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); 10279 HValue* key_constant = AddInstruction(new(zone) HConstant(i));
10252 if (value->IsJSObject()) { 10280 if (value->IsJSObject()) {
10253 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 10281 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
10254 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 10282 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
11003 11031
11004 HEnvironment::HEnvironment(HEnvironment* outer, 11032 HEnvironment::HEnvironment(HEnvironment* outer,
11005 Handle<JSFunction> closure, 11033 Handle<JSFunction> closure,
11006 FrameType frame_type, 11034 FrameType frame_type,
11007 int arguments, 11035 int arguments,
11008 Zone* zone) 11036 Zone* zone)
11009 : closure_(closure), 11037 : closure_(closure),
11010 values_(arguments, zone), 11038 values_(arguments, zone),
11011 frame_type_(frame_type), 11039 frame_type_(frame_type),
11012 parameter_count_(arguments), 11040 parameter_count_(arguments),
11041 specials_count_(0),
11013 local_count_(0), 11042 local_count_(0),
11014 outer_(outer), 11043 outer_(outer),
11015 entry_(NULL), 11044 entry_(NULL),
11016 pop_count_(0), 11045 pop_count_(0),
11017 push_count_(0), 11046 push_count_(0),
11018 ast_id_(BailoutId::None()), 11047 ast_id_(BailoutId::None()),
11019 zone_(zone) { 11048 zone_(zone) {
11020 } 11049 }
11021 11050
11022 11051
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
11549 names_.Add(name); 11578 names_.Add(name);
11550 timing_.Add(ticks); 11579 timing_.Add(ticks);
11551 sizes_.Add(size); 11580 sizes_.Add(size);
11552 } 11581 }
11553 } 11582 }
11554 11583
11555 11584
11556 const char* const HPhase::kFullCodeGen = "Full code generator"; 11585 const char* const HPhase::kFullCodeGen = "Full code generator";
11557 11586
11558 11587
11559 HPhase::HPhase(const char* name, Isolate* isolate) { 11588 HPhase::HPhase(const char* name, Isolate* isolate, Zone* zone) {
11560 Init(isolate, name, NULL, NULL, NULL); 11589 Init(isolate, name, zone, NULL, NULL, NULL);
11561 } 11590 }
11562 11591
11563 11592
11564 HPhase::HPhase(const char* name, HGraph* graph) { 11593 HPhase::HPhase(const char* name, HGraph* graph) {
11565 Init(graph->isolate(), name, graph, NULL, NULL); 11594 Init(graph->isolate(), name, graph->zone(), graph, NULL, NULL);
11566 } 11595 }
11567 11596
11568 11597
11569 HPhase::HPhase(const char* name, LChunk* chunk) { 11598 HPhase::HPhase(const char* name, LChunk* chunk) {
11570 Init(chunk->isolate(), name, NULL, chunk, NULL); 11599 Init(chunk->isolate(), name, chunk->zone(), NULL, chunk, NULL);
11571 } 11600 }
11572 11601
11573 11602
11574 HPhase::HPhase(const char* name, LAllocator* allocator) { 11603 HPhase::HPhase(const char* name, LAllocator* allocator) {
11575 Init(allocator->isolate(), name, NULL, NULL, allocator); 11604 Init(allocator->isolate(), name, allocator->zone(), NULL, NULL, allocator);
11576 } 11605 }
11577 11606
11578 11607
11579 void HPhase::Init(Isolate* isolate, 11608 void HPhase::Init(Isolate* isolate,
11580 const char* name, 11609 const char* name,
11610 Zone* zone,
11581 HGraph* graph, 11611 HGraph* graph,
11582 LChunk* chunk, 11612 LChunk* chunk,
11583 LAllocator* allocator) { 11613 LAllocator* allocator) {
11584 isolate_ = isolate; 11614 isolate_ = isolate;
11585 name_ = name; 11615 name_ = name;
11616 zone_ = zone;
11586 graph_ = graph; 11617 graph_ = graph;
11587 chunk_ = chunk; 11618 chunk_ = chunk;
11588 allocator_ = allocator; 11619 allocator_ = allocator;
11589 if (allocator != NULL && chunk_ == NULL) { 11620 if (allocator != NULL && chunk_ == NULL) {
11590 chunk_ = allocator->chunk(); 11621 chunk_ = allocator->chunk();
11591 } 11622 }
11592 if (FLAG_hydrogen_stats) { 11623 if (FLAG_hydrogen_stats) {
11593 start_ticks_ = OS::Ticks(); 11624 start_ticks_ = OS::Ticks();
11594 start_allocation_size_ = Zone::allocation_size_; 11625 start_allocation_size_ = zone_->allocation_size();
11595 } 11626 }
11596 } 11627 }
11597 11628
11598 11629
11599 HPhase::~HPhase() { 11630 HPhase::~HPhase() {
11600 if (FLAG_hydrogen_stats) { 11631 if (FLAG_hydrogen_stats) {
11601 int64_t ticks = OS::Ticks() - start_ticks_; 11632 int64_t ticks = OS::Ticks() - start_ticks_;
11602 unsigned size = Zone::allocation_size_ - start_allocation_size_; 11633 unsigned size = zone_->allocation_size() - start_allocation_size_;
11603 isolate_->GetHStatistics()->SaveTiming(name_, ticks, size); 11634 isolate_->GetHStatistics()->SaveTiming(name_, ticks, size);
11604 } 11635 }
11605 11636
11606 // Produce trace output if flag is set so that the first letter of the 11637 // Produce trace output if flag is set so that the first letter of the
11607 // phase name matches the command line parameter FLAG_trace_phase. 11638 // phase name matches the command line parameter FLAG_trace_phase.
11608 if (FLAG_trace_hydrogen && 11639 if (FLAG_trace_hydrogen &&
11609 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL) { 11640 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL) {
11610 if (graph_ != NULL) { 11641 if (graph_ != NULL) {
11611 isolate_->GetHTracer()->TraceHydrogen(name_, graph_); 11642 isolate_->GetHTracer()->TraceHydrogen(name_, graph_);
11612 } 11643 }
11613 if (chunk_ != NULL) { 11644 if (chunk_ != NULL) {
11614 isolate_->GetHTracer()->TraceLithium(name_, chunk_); 11645 isolate_->GetHTracer()->TraceLithium(name_, chunk_);
11615 } 11646 }
11616 if (allocator_ != NULL) { 11647 if (allocator_ != NULL) {
11617 isolate_->GetHTracer()->TraceLiveRanges(name_, allocator_); 11648 isolate_->GetHTracer()->TraceLiveRanges(name_, allocator_);
11618 } 11649 }
11619 } 11650 }
11620 11651
11621 #ifdef DEBUG 11652 #ifdef DEBUG
11622 if (graph_ != NULL) graph_->Verify(false); // No full verify. 11653 if (graph_ != NULL) graph_->Verify(false); // No full verify.
11623 if (allocator_ != NULL) allocator_->Verify(); 11654 if (allocator_ != NULL) allocator_->Verify();
11624 #endif 11655 #endif
11625 } 11656 }
11626 11657
11627 } } // namespace v8::internal 11658 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698