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

Side by Side Diff: src/hydrogen.cc

Issue 14284010: Introduce HObjectAccess, which is used by LoadNamedField and StoreNamedField to denote what parts (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 8 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
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 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 1182
1183 environment()->Push(elements); 1183 environment()->Push(elements);
1184 capacity_checker.End(); 1184 capacity_checker.End();
1185 1185
1186 if (is_js_array) { 1186 if (is_js_array) {
1187 HValue* new_length = AddInstruction( 1187 HValue* new_length = AddInstruction(
1188 HAdd::New(zone, context, length, graph_->GetConstant1())); 1188 HAdd::New(zone, context, length, graph_->GetConstant1()));
1189 new_length->ChangeRepresentation(Representation::Integer32()); 1189 new_length->ChangeRepresentation(Representation::Integer32());
1190 new_length->ClearFlag(HValue::kCanOverflow); 1190 new_length->ClearFlag(HValue::kCanOverflow);
1191 1191
1192 Factory* factory = isolate()->factory(); 1192 AddStore(object, AccessArrayLength(), new_length);
1193 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField(
1194 object,
1195 factory->length_field_string(),
1196 new_length, true,
1197 JSArray::kLengthOffset));
1198 length_store->SetGVNFlag(kChangesArrayLengths);
1199 } 1193 }
1200 1194
1201 length_checker.Else(); 1195 length_checker.Else();
1202 1196
1203 AddBoundsCheck(key, length, ALLOW_SMI_KEY); 1197 AddBoundsCheck(key, length, ALLOW_SMI_KEY);
1204 environment()->Push(elements); 1198 environment()->Push(elements);
1205 1199
1206 length_checker.End(); 1200 length_checker.End();
1207 1201
1208 return environment()->Pop(); 1202 return environment()->Pop();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 AddInstruction(new(zone) HLoadElements(object, mapcheck)); 1264 AddInstruction(new(zone) HLoadElements(object, mapcheck));
1271 if (is_store && (fast_elements || fast_smi_only_elements) && 1265 if (is_store && (fast_elements || fast_smi_only_elements) &&
1272 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 1266 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
1273 HCheckMaps* check_cow_map = HCheckMaps::New( 1267 HCheckMaps* check_cow_map = HCheckMaps::New(
1274 elements, isolate()->factory()->fixed_array_map(), zone); 1268 elements, isolate()->factory()->fixed_array_map(), zone);
1275 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1269 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1276 AddInstruction(check_cow_map); 1270 AddInstruction(check_cow_map);
1277 } 1271 }
1278 HInstruction* length = NULL; 1272 HInstruction* length = NULL;
1279 if (is_js_array) { 1273 if (is_js_array) {
1280 length = AddInstruction( 1274 length = AddInstruction(
danno 2013/04/26 09:39:38 while your here, and you add a AddLoad (like your
1281 HLoadNamedField::NewArrayLength(zone, object, mapcheck, HType::Smi())); 1275 new(zone) HLoadNamedField(object, AccessArrayLength(), mapcheck));
1276 length->set_type(HType::Smi());
1282 } else { 1277 } else {
1283 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); 1278 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements));
1284 } 1279 }
1285 HValue* checked_key = NULL; 1280 HValue* checked_key = NULL;
1286 if (IsExternalArrayElementsKind(elements_kind)) { 1281 if (IsExternalArrayElementsKind(elements_kind)) {
1287 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 1282 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
1288 NoObservableSideEffectsScope no_effects(this); 1283 NoObservableSideEffectsScope no_effects(this);
1289 HLoadExternalArrayPointer* external_elements = 1284 HLoadExternalArrayPointer* external_elements =
1290 new(zone) HLoadExternalArrayPointer(elements); 1285 new(zone) HLoadExternalArrayPointer(elements);
1291 AddInstruction(external_elements); 1286 AddInstruction(external_elements);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 1399
1405 1400
1406 void HGraphBuilder::BuildInitializeElements(HValue* elements, 1401 void HGraphBuilder::BuildInitializeElements(HValue* elements,
1407 ElementsKind kind, 1402 ElementsKind kind,
1408 HValue* capacity) { 1403 HValue* capacity) {
1409 Zone* zone = this->zone(); 1404 Zone* zone = this->zone();
1410 Factory* factory = isolate()->factory(); 1405 Factory* factory = isolate()->factory();
1411 Handle<Map> map = IsFastDoubleElementsKind(kind) 1406 Handle<Map> map = IsFastDoubleElementsKind(kind)
1412 ? factory->fixed_double_array_map() 1407 ? factory->fixed_double_array_map()
1413 : factory->fixed_array_map(); 1408 : factory->fixed_array_map();
1414 BuildStoreMap(elements, map);
1415 1409
1416 Handle<String> fixed_array_length_field_name = factory->length_field_string(); 1410 HValue* map_constant =
1417 HInstruction* store_length = 1411 AddInstruction(new(zone) HConstant(map, Representation::Tagged()));
1418 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, 1412 AddStore(elements, AccessMap(), map_constant);
1419 capacity, true, FixedArray::kLengthOffset); 1413 AddStore(elements, AccessFixedArrayLength(), capacity);
1420 AddInstruction(store_length);
1421 } 1414 }
1422 1415
1423 1416
1424 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, 1417 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context,
1425 ElementsKind kind, 1418 ElementsKind kind,
1426 HValue* capacity) { 1419 HValue* capacity) {
1427 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1420 HValue* new_elements = BuildAllocateElements(context, kind, capacity);
1428 BuildInitializeElements(new_elements, kind, capacity); 1421 BuildInitializeElements(new_elements, kind, capacity);
1429 return new_elements; 1422 return new_elements;
1430 } 1423 }
1431 1424
1432 1425
1433 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
1434 HValue* map) {
1435 Zone* zone = this->zone();
1436 Factory* factory = isolate()->factory();
1437 Handle<String> map_field_name = factory->map_field_string();
1438 HInstruction* store_map =
1439 new(zone) HStoreNamedField(object, map_field_name, map,
1440 true, JSObject::kMapOffset);
1441 store_map->SetGVNFlag(kChangesMaps);
1442 AddInstruction(store_map);
1443 return store_map;
1444 }
1445
1446
1447 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
1448 Handle<Map> map) {
1449 Zone* zone = this->zone();
1450 HValue* map_constant =
1451 AddInstruction(new(zone) HConstant(map, Representation::Tagged()));
1452 return BuildStoreMap(object, map_constant);
1453 }
1454
1455
1456 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, 1426 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context,
1457 HValue* old_capacity) { 1427 HValue* old_capacity) {
1458 Zone* zone = this->zone(); 1428 Zone* zone = this->zone();
1459 HValue* half_old_capacity = 1429 HValue* half_old_capacity =
1460 AddInstruction(HShr::New(zone, context, old_capacity, 1430 AddInstruction(HShr::New(zone, context, old_capacity,
1461 graph_->GetConstant1())); 1431 graph_->GetConstant1()));
1462 half_old_capacity->ChangeRepresentation(Representation::Integer32()); 1432 half_old_capacity->ChangeRepresentation(Representation::Integer32());
1463 half_old_capacity->ClearFlag(HValue::kCanOverflow); 1433 half_old_capacity->ClearFlag(HValue::kCanOverflow);
1464 1434
1465 HValue* new_capacity = AddInstruction( 1435 HValue* new_capacity = AddInstruction(
(...skipping 29 matching lines...) Expand all
1495 HBoundsCheck(length, max_size_constant, 1465 HBoundsCheck(length, max_size_constant,
1496 DONT_ALLOW_SMI_KEY, Representation::Integer32())); 1466 DONT_ALLOW_SMI_KEY, Representation::Integer32()));
1497 } 1467 }
1498 1468
1499 1469
1500 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, 1470 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object,
1501 HValue* elements, 1471 HValue* elements,
1502 ElementsKind kind, 1472 ElementsKind kind,
1503 HValue* length, 1473 HValue* length,
1504 HValue* new_capacity) { 1474 HValue* new_capacity) {
1505 Zone* zone = this->zone();
1506 HValue* context = environment()->LookupContext(); 1475 HValue* context = environment()->LookupContext();
1507 1476
1508 BuildNewSpaceArrayCheck(new_capacity, kind); 1477 BuildNewSpaceArrayCheck(new_capacity, kind);
1509 1478
1510 HValue* new_elements = 1479 HValue* new_elements =
1511 BuildAllocateAndInitializeElements(context, kind, new_capacity); 1480 BuildAllocateAndInitializeElements(context, kind, new_capacity);
1512 1481
1513 BuildCopyElements(context, elements, kind, 1482 BuildCopyElements(context, elements, kind,
1514 new_elements, kind, 1483 new_elements, kind,
1515 length, new_capacity); 1484 length, new_capacity);
1516 1485
1517 Factory* factory = isolate()->factory(); 1486 AddStore(object, AccessElements(), new_elements);
1518 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField(
1519 object,
1520 factory->elements_field_string(),
1521 new_elements, true,
1522 JSArray::kElementsOffset));
1523 elements_store->SetGVNFlag(kChangesElementsPointer);
1524 1487
1525 return new_elements; 1488 return new_elements;
1526 } 1489 }
1527 1490
1528 1491
1529 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, 1492 void HGraphBuilder::BuildFillElementsWithHole(HValue* context,
1530 HValue* elements, 1493 HValue* elements,
1531 ElementsKind elements_kind, 1494 ElementsKind elements_kind,
1532 HValue* from, 1495 HValue* from,
1533 HValue* to) { 1496 HValue* to) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); 1591 AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
1629 HInstruction* object = 1592 HInstruction* object =
1630 AddInstruction(new(zone) HAllocate(context, 1593 AddInstruction(new(zone) HAllocate(context,
1631 size_in_bytes, 1594 size_in_bytes,
1632 HType::JSObject(), 1595 HType::JSObject(),
1633 allocate_flags)); 1596 allocate_flags));
1634 1597
1635 // Copy the JS array part. 1598 // Copy the JS array part.
1636 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { 1599 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
1637 if ((i != JSArray::kElementsOffset) || (length == 0)) { 1600 if ((i != JSArray::kElementsOffset) || (length == 0)) {
1601 ObjectAccess access = AccessArray(i);
danno 2013/04/26 09:39:38 Careful, this isn't what you think. This loop does
1638 HInstruction* value = 1602 HInstruction* value =
1639 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); 1603 AddInstruction(new(zone) HLoadNamedField(boilerplate, access));
1640 if (i != JSArray::kMapOffset) { 1604 AddStore(object, access, value);
1641 AddInstruction(new(zone) HStoreNamedField(object,
1642 factory->empty_string(),
1643 value,
1644 true, i));
1645 } else {
1646 BuildStoreMap(object, value);
1647 }
1648 } 1605 }
1649 } 1606 }
1650 1607
1651 // Create an allocation site info if requested. 1608 // Create an allocation site info if requested.
1652 if (mode == TRACK_ALLOCATION_SITE) { 1609 if (mode == TRACK_ALLOCATION_SITE) {
1653 HValue* alloc_site = 1610 HValue* alloc_site =
1654 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize)); 1611 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize));
1655 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); 1612 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
1656 BuildStoreMap(alloc_site, alloc_site_map); 1613 HValue* alloc_site_map_constant = AddInstruction(new(zone)
1657 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; 1614 HConstant(alloc_site_map, Representation::Tagged()));
1658 AddInstruction(new(zone) HStoreNamedField(alloc_site, 1615 AddStore(alloc_site, AccessMap(), alloc_site_map_constant);
danno 2013/04/26 09:39:38 I still think a wrapper utility BuildStoreMap woul
1659 factory->empty_string(), 1616 ObjectAccess access = AccessInobject(
1660 boilerplate, 1617 factory->payload_string(), AllocationSiteInfo::kPayloadOffset);
1661 true, alloc_payload_offset)); 1618 AddStore(alloc_site, access, boilerplate);
1662 } 1619 }
1663 1620
1664 if (length > 0) { 1621 if (length > 0) {
1665 // Get hold of the elements array of the boilerplate and setup the 1622 // Get hold of the elements array of the boilerplate and setup the
1666 // elements pointer in the resulting object. 1623 // elements pointer in the resulting object.
1667 HValue* boilerplate_elements = 1624 HValue* boilerplate_elements =
1668 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); 1625 AddInstruction(new(zone) HLoadElements(boilerplate, NULL));
1669 HValue* object_elements = 1626 HValue* object_elements =
1670 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); 1627 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset));
1671 AddInstruction(new(zone) HStoreNamedField(object, 1628 AddStore(object, AccessElements(), object_elements);
1672 factory->elements_field_string(),
1673 object_elements,
1674 true, JSObject::kElementsOffset));
1675 1629
1676 // Copy the elements array header. 1630 // Copy the elements array header.
1677 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { 1631 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
1678 HInstruction* value = 1632 // TODO(titzer): AccessFixedArray?
1679 AddInstruction(new(zone) HLoadNamedField(boilerplate_elements, 1633 ObjectAccess access = AccessInobject(factory->empty_string(), i);
1680 true, i)); 1634 HInstruction* value = AddInstruction(new(zone)
1681 AddInstruction(new(zone) HStoreNamedField(object_elements, 1635 HLoadNamedField(boilerplate_elements, access));
1682 factory->empty_string(), 1636 AddStore(object_elements, access, value);
1683 value,
1684 true, i));
1685 } 1637 }
1686 1638
1687 // Copy the elements array contents. 1639 // Copy the elements array contents.
1688 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold 1640 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold
1689 // copying loops with constant length up to a given boundary and use this 1641 // copying loops with constant length up to a given boundary and use this
1690 // helper here instead. 1642 // helper here instead.
1691 for (int i = 0; i < length; i++) { 1643 for (int i = 0; i < length; i++) {
1692 HValue* key_constant = 1644 HValue* key_constant =
1693 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); 1645 AddInstruction(new(zone) HConstant(i, Representation::Integer32()));
1694 HInstruction* value = 1646 HInstruction* value =
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 if (kind == kNonStrictEquality) { 1699 if (kind == kNonStrictEquality) {
1748 if_nil.Deopt(); 1700 if_nil.Deopt();
1749 } 1701 }
1750 } 1702 }
1751 } 1703 }
1752 1704
1753 if_nil.CaptureContinuation(continuation); 1705 if_nil.CaptureContinuation(continuation);
1754 } 1706 }
1755 1707
1756 1708
1709 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, ObjectAccess access,
1710 HValue *val) {
1711 HStoreNamedField *instr = new(zone()) HStoreNamedField(object, access, val);
1712 AddInstruction(instr);
1713 return instr;
1714 }
1715
1716
1717 ObjectAccess HGraphBuilder::AccessArray(int offset) {
1718 Factory *factory = isolate()->factory();
1719 ObjectAccess::Portion portion = ObjectAccess::kInobject;
1720 Handle<String> name = factory->empty_string();
1721 if (offset == JSObject::kElementsOffset) {
1722 portion = ObjectAccess::kElementsPointer;
1723 name = factory->elements_field_string();
1724 } else if (offset == JSArray::kLengthOffset) {
1725 portion = ObjectAccess::kArrayLengths;
1726 name = factory->length_field_string();
1727 } else if (offset == JSArray::kMapOffset) {
1728 portion = ObjectAccess::kMaps;
1729 name = factory->map_field_string();
danno 2013/04/26 09:39:38 See my other comments about consolidating this log
1730 }
1731 return ObjectAccess(portion, offset, false, name);
1732 }
1733
1734
1735 ObjectAccess HGraphBuilder::AccessArrayLength() {
1736 return ObjectAccess(ObjectAccess::kArrayLengths, JSArray::kLengthOffset,
1737 false, isolate()->factory()->length_field_string());
1738 }
1739
1740
1741 ObjectAccess HGraphBuilder::AccessFixedArrayLength() {
1742 return ObjectAccess(ObjectAccess::kInobject, FixedArray::kLengthOffset,
1743 false, isolate()->factory()->length_field_string());
1744 }
1745
1746
1747 ObjectAccess HGraphBuilder::AccessElements() {
1748 return ObjectAccess(ObjectAccess::kElementsPointer, JSObject::kElementsOffset,
1749 false, isolate()->factory()->elements_field_string());
1750 }
1751
1752
1753 ObjectAccess HGraphBuilder::AccessMap() {
1754 return ObjectAccess(ObjectAccess::kMaps, JSObject::kMapOffset,
1755 false, isolate()->factory()->map_field_string());
1756 }
1757
1758
1759 ObjectAccess HGraphBuilder::AccessField(Handle<Map> map, Handle<String> name,
1760 LookupResult* lookup) {
1761 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*map));
1762 int index;
1763 if (lookup->IsField()) {
1764 index = lookup->GetLocalFieldIndexFromMap(*map);
1765 } else {
1766 Map* transition = lookup->GetTransitionMapFromMap(*map);
1767 index = transition->PropertyIndexFor(*name) - map->inobject_properties();
1768 }
1769 if (index < 0) {
1770 // Negative property indices are in-object properties, indexed
1771 // from the end of the fixed part of the object.
1772 int offset = (index * kPointerSize) + map->instance_size();
1773 return ObjectAccess(ObjectAccess::kInobject, offset, false);
1774 } else {
1775 // Non-negative property indices are in the properties array.
1776 int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
1777 return ObjectAccess(ObjectAccess::kBackingStore, offset, false, name);
1778 }
1779 }
1780
1781 ObjectAccess HGraphBuilder::AccessInobject(Handle<String> name, int offset) {
1782 return ObjectAccess(ObjectAccess::kInobject, offset, false, name);
1783 }
1784
1785
1757 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, 1786 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
1758 TypeFeedbackOracle* oracle) 1787 TypeFeedbackOracle* oracle)
1759 : HGraphBuilder(info), 1788 : HGraphBuilder(info),
1760 function_state_(NULL), 1789 function_state_(NULL),
1761 initial_function_state_(this, info, oracle, NORMAL_RETURN), 1790 initial_function_state_(this, info, oracle, NORMAL_RETURN),
1762 ast_context_(NULL), 1791 ast_context_(NULL),
1763 break_scope_(NULL), 1792 break_scope_(NULL),
1764 inlined_count_(0), 1793 inlined_count_(0),
1765 globals_(10, info->zone()), 1794 globals_(10, info->zone()),
1766 inline_bailout_(false) { 1795 inline_bailout_(false) {
(...skipping 4887 matching lines...) Expand 10 before | Expand all | Expand 10 after
6654 if (!is_store) return false; 6683 if (!is_store) return false;
6655 6684
6656 // 2nd chance: A store into a non-existent field can still be inlined if we 6685 // 2nd chance: A store into a non-existent field can still be inlined if we
6657 // have a matching transition and some room left in the object. 6686 // have a matching transition and some room left in the object.
6658 type->LookupTransition(NULL, *name, lookup); 6687 type->LookupTransition(NULL, *name, lookup);
6659 return lookup->IsTransitionToField(*type) && 6688 return lookup->IsTransitionToField(*type) &&
6660 (type->unused_property_fields() > 0); 6689 (type->unused_property_fields() > 0);
6661 } 6690 }
6662 6691
6663 6692
6664 static int ComputeLoadStoreFieldIndex(Handle<Map> type,
6665 Handle<String> name,
6666 LookupResult* lookup) {
6667 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type));
6668 if (lookup->IsField()) {
6669 return lookup->GetLocalFieldIndexFromMap(*type);
6670 } else {
6671 Map* transition = lookup->GetTransitionMapFromMap(*type);
6672 return transition->PropertyIndexFor(*name) - type->inobject_properties();
6673 }
6674 }
6675
6676
6677 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { 6693 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
6678 AddInstruction(new(zone()) HCheckNonSmi(object)); 6694 AddInstruction(new(zone()) HCheckNonSmi(object));
6679 AddInstruction(HCheckMaps::New(object, map, zone())); 6695 AddInstruction(HCheckMaps::New(object, map, zone()));
6680 } 6696 }
6681 6697
6682 6698
6683 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, 6699 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object,
6684 Handle<Map> map) { 6700 Handle<Map> map) {
6685 AddInstruction(new(zone()) HCheckNonSmi(object)); 6701 AddInstruction(new(zone()) HCheckNonSmi(object));
6686 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); 6702 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
(...skipping 30 matching lines...) Expand all
6717 } 6733 }
6718 ASSERT(proto->GetPrototype(isolate())->IsNull()); 6734 ASSERT(proto->GetPrototype(isolate())->IsNull());
6719 } 6735 }
6720 ASSERT(proto->IsJSObject()); 6736 ASSERT(proto->IsJSObject());
6721 AddInstruction(new(zone()) HCheckPrototypeMaps( 6737 AddInstruction(new(zone()) HCheckPrototypeMaps(
6722 Handle<JSObject>(JSObject::cast(map->prototype())), 6738 Handle<JSObject>(JSObject::cast(map->prototype())),
6723 Handle<JSObject>(JSObject::cast(proto)), 6739 Handle<JSObject>(JSObject::cast(proto)),
6724 zone())); 6740 zone()));
6725 } 6741 }
6726 6742
6727 int index = ComputeLoadStoreFieldIndex(map, name, lookup); 6743 ObjectAccess access = AccessField(map, name, lookup);
6728 bool is_in_object = index < 0; 6744 HStoreNamedField* instr = new(zone()) HStoreNamedField(object, access, value);
6729 int offset = index * kPointerSize;
6730 if (index < 0) {
6731 // Negative property indices are in-object properties, indexed
6732 // from the end of the fixed part of the object.
6733 offset += map->instance_size();
6734 } else {
6735 offset += FixedArray::kHeaderSize;
6736 }
6737 HStoreNamedField* instr =
6738 new(zone()) HStoreNamedField(object, name, value, is_in_object, offset);
6739 if (lookup->IsTransitionToField(*map)) { 6745 if (lookup->IsTransitionToField(*map)) {
6740 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); 6746 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
6741 instr->set_transition(transition); 6747 instr->set_transition(transition);
6742 // TODO(fschneider): Record the new map type of the object in the IR to 6748 // TODO(fschneider): Record the new map type of the object in the IR to
6743 // enable elimination of redundant checks after the transition store. 6749 // enable elimination of redundant checks after the transition store.
6744 instr->SetGVNFlag(kChangesMaps); 6750 instr->SetGVNFlag(kChangesMaps);
6745 } 6751 }
6746 return instr; 6752 return instr;
6747 } 6753 }
6748 6754
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
6800 6806
6801 for (int i = 0; i < types->length(); i++) { 6807 for (int i = 0; i < types->length(); i++) {
6802 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; 6808 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false;
6803 } 6809 }
6804 6810
6805 AddInstruction(new(zone()) HCheckNonSmi(object)); 6811 AddInstruction(new(zone()) HCheckNonSmi(object));
6806 6812
6807 HInstruction* typecheck = 6813 HInstruction* typecheck =
6808 AddInstruction(HCheckMaps::New(object, types, zone())); 6814 AddInstruction(HCheckMaps::New(object, types, zone()));
6809 HInstruction* instr = 6815 HInstruction* instr =
6810 HLoadNamedField::NewArrayLength(zone(), object, typecheck); 6816 new(zone()) HLoadNamedField(object, AccessArrayLength(), typecheck);
6817
6811 instr->set_position(expr->position()); 6818 instr->set_position(expr->position());
6812 ast_context()->ReturnInstruction(instr, expr->id()); 6819 ast_context()->ReturnInstruction(instr, expr->id());
6813 return true; 6820 return true;
6814 } 6821 }
6815 6822
6816 6823
6817 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, 6824 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
6818 HValue* object, 6825 HValue* object,
6819 SmallMapList* types, 6826 SmallMapList* types,
6820 Handle<String> name) { 6827 Handle<String> name) {
6821 int count = 0; 6828 int count = 0;
6822 int previous_field_offset = 0; 6829 int previous_field_offset = 0;
6823 bool previous_field_is_in_object = false; 6830 bool previous_field_is_in_object = false;
6824 bool is_monomorphic_field = true; 6831 bool is_monomorphic_field = true;
6825 6832
6826 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) 6833 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name))
6827 return; 6834 return;
6828 6835
6829 Handle<Map> map; 6836 Handle<Map> map;
6830 LookupResult lookup(isolate()); 6837 LookupResult lookup(isolate());
6831 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { 6838 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
6832 map = types->at(i); 6839 map = types->at(i);
6833 if (ComputeLoadStoreField(map, name, &lookup, false)) { 6840 if (ComputeLoadStoreField(map, name, &lookup, false)) {
6834 int index = ComputeLoadStoreFieldIndex(map, name, &lookup); 6841 ObjectAccess access = AccessField(map, name, &lookup);
6835 bool is_in_object = index < 0;
6836 int offset = index * kPointerSize;
6837 if (index < 0) {
6838 // Negative property indices are in-object properties, indexed
6839 // from the end of the fixed part of the object.
6840 offset += map->instance_size();
6841 } else {
6842 offset += FixedArray::kHeaderSize;
6843 }
6844 if (count == 0) { 6842 if (count == 0) {
6845 previous_field_offset = offset; 6843 previous_field_offset = access.offset();
6846 previous_field_is_in_object = is_in_object; 6844 previous_field_is_in_object = access.IsInobject();
6847 } else if (is_monomorphic_field) { 6845 } else if (is_monomorphic_field) {
6848 is_monomorphic_field = (offset == previous_field_offset) && 6846 // TODO(titzer): just break out of this loop if not the same
6849 (is_in_object == previous_field_is_in_object); 6847 is_monomorphic_field =
6848 (access.offset() == previous_field_offset) &&
6849 (access.IsInobject() == previous_field_is_in_object);
6850 } 6850 }
6851 ++count; 6851 ++count;
6852 } 6852 }
6853 } 6853 }
6854 6854
6855 // Use monomorphic load if property lookup results in the same field index 6855 // Use monomorphic load if property lookup results in the same field index
6856 // for all maps. Requires special map check on the set of all handled maps. 6856 // for all maps. Requires special map check on the set of all handled maps.
6857 AddInstruction(new(zone()) HCheckNonSmi(object)); 6857 AddInstruction(new(zone()) HCheckNonSmi(object));
6858 HInstruction* instr; 6858 HInstruction* instr;
6859 if (count == types->length() && is_monomorphic_field) { 6859 if (count == types->length() && is_monomorphic_field) {
6860 AddInstruction(HCheckMaps::New(object, types, zone())); 6860 AddInstruction(HCheckMaps::New(object, types, zone()));
6861 instr = BuildLoadNamedField(object, map, &lookup); 6861 instr = new(zone())
6862 HLoadNamedField(object, AccessField(map, name, &lookup));
6862 } else { 6863 } else {
6863 HValue* context = environment()->LookupContext(); 6864 HValue* context = environment()->LookupContext();
6864 instr = new(zone()) HLoadNamedFieldPolymorphic(context, 6865 instr = new(zone())
6865 object, 6866 HLoadNamedFieldPolymorphic(context, object, types, name, zone());
6866 types,
6867 name,
6868 zone());
6869 } 6867 }
6870 6868
6871 instr->set_position(expr->position()); 6869 instr->set_position(expr->position());
6872 return ast_context()->ReturnInstruction(instr, expr->id()); 6870 return ast_context()->ReturnInstruction(instr, expr->id());
6873 } 6871 }
6874 6872
6875 6873
6876 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 6874 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
6877 Assignment* expr, 6875 Assignment* expr,
6878 HValue* object, 6876 HValue* object,
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
7411 HValue* value = environment()->Pop(); 7409 HValue* value = environment()->Pop();
7412 HThrow* instr = new(zone()) HThrow(context, value); 7410 HThrow* instr = new(zone()) HThrow(context, value);
7413 instr->set_position(expr->position()); 7411 instr->set_position(expr->position());
7414 AddInstruction(instr); 7412 AddInstruction(instr);
7415 AddSimulate(expr->id()); 7413 AddSimulate(expr->id());
7416 current_block()->FinishExit(new(zone()) HAbnormalExit); 7414 current_block()->FinishExit(new(zone()) HAbnormalExit);
7417 set_current_block(NULL); 7415 set_current_block(NULL);
7418 } 7416 }
7419 7417
7420 7418
7421 HLoadNamedField* HOptimizedGraphBuilder::BuildLoadNamedField(
7422 HValue* object,
7423 Handle<Map> map,
7424 LookupResult* lookup) {
7425 int index = lookup->GetLocalFieldIndexFromMap(*map);
7426 if (index < 0) {
7427 // Negative property indices are in-object properties, indexed
7428 // from the end of the fixed part of the object.
7429 int offset = (index * kPointerSize) + map->instance_size();
7430 return new(zone()) HLoadNamedField(object, true, offset);
7431 } else {
7432 // Non-negative property indices are in the properties array.
7433 int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
7434 return new(zone()) HLoadNamedField(object, false, offset);
7435 }
7436 }
7437
7438
7439 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 7419 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
7440 HValue* object, 7420 HValue* object,
7441 Handle<String> name, 7421 Handle<String> name,
7442 Property* expr) { 7422 Property* expr) {
7443 if (expr->IsUninitialized()) { 7423 if (expr->IsUninitialized()) {
7444 AddSoftDeoptimize(); 7424 AddSoftDeoptimize();
7445 } 7425 }
7446 HValue* context = environment()->LookupContext(); 7426 HValue* context = environment()->LookupContext();
7447 return new(zone()) HLoadNamedGeneric(context, object, name); 7427 return new(zone()) HLoadNamedGeneric(context, object, name);
7448 } 7428 }
(...skipping 15 matching lines...) Expand all
7464 Handle<String> name, 7444 Handle<String> name,
7465 Property* expr, 7445 Property* expr,
7466 Handle<Map> map) { 7446 Handle<Map> map) {
7467 // Handle a load from a known field. 7447 // Handle a load from a known field.
7468 ASSERT(!map->is_dictionary_map()); 7448 ASSERT(!map->is_dictionary_map());
7469 7449
7470 // Handle access to various length properties 7450 // Handle access to various length properties
7471 if (name->Equals(isolate()->heap()->length_string())) { 7451 if (name->Equals(isolate()->heap()->length_string())) {
7472 if (map->instance_type() == JS_ARRAY_TYPE) { 7452 if (map->instance_type() == JS_ARRAY_TYPE) {
7473 AddCheckMapsWithTransitions(object, map); 7453 AddCheckMapsWithTransitions(object, map);
7474 return HLoadNamedField::NewArrayLength(zone(), object, object); 7454 return new(zone()) HLoadNamedField(object, AccessArrayLength());
7475 } 7455 }
7476 } 7456 }
7477 7457
7478 LookupResult lookup(isolate()); 7458 LookupResult lookup(isolate());
7479 map->LookupDescriptor(NULL, *name, &lookup); 7459 map->LookupDescriptor(NULL, *name, &lookup);
7480 if (lookup.IsField()) { 7460 if (lookup.IsField()) {
7481 AddCheckMap(object, map); 7461 AddCheckMap(object, map);
7482 return BuildLoadNamedField(object, map, &lookup); 7462 return new(zone()) HLoadNamedField(object, AccessField(map, name, &lookup));
7483 } 7463 }
7484 7464
7485 // Handle a load of a constant known function. 7465 // Handle a load of a constant known function.
7486 if (lookup.IsConstantFunction()) { 7466 if (lookup.IsConstantFunction()) {
7487 AddCheckMap(object, map); 7467 AddCheckMap(object, map);
7488 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); 7468 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
7489 return new(zone()) HConstant(function, Representation::Tagged()); 7469 return new(zone()) HConstant(function, Representation::Tagged());
7490 } 7470 }
7491 7471
7492 // Handle a load from a known field somewhere in the prototype chain. 7472 // Handle a load from a known field somewhere in the prototype chain.
7493 LookupInPrototypes(map, name, &lookup); 7473 LookupInPrototypes(map, name, &lookup);
7494 if (lookup.IsField()) { 7474 if (lookup.IsField()) {
7495 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 7475 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
7496 Handle<JSObject> holder(lookup.holder()); 7476 Handle<JSObject> holder(lookup.holder());
7497 Handle<Map> holder_map(holder->map()); 7477 Handle<Map> holder_map(holder->map());
7498 AddCheckMap(object, map); 7478 AddCheckMap(object, map);
7499 AddInstruction( 7479 AddInstruction(new(zone())
7500 new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); 7480 HCheckPrototypeMaps(prototype, holder, zone()));
7501 HValue* holder_value = AddInstruction( 7481 HValue* holder_value = AddInstruction(new(zone())
7502 new(zone()) HConstant(holder, Representation::Tagged())); 7482 HConstant(holder, Representation::Tagged()));
7503 return BuildLoadNamedField(holder_value, holder_map, &lookup); 7483 return new(zone())
7484 HLoadNamedField(holder_value, AccessField(holder_map, name, &lookup));
7504 } 7485 }
7505 7486
7506 // Handle a load of a constant function somewhere in the prototype chain. 7487 // Handle a load of a constant function somewhere in the prototype chain.
7507 if (lookup.IsConstantFunction()) { 7488 if (lookup.IsConstantFunction()) {
7508 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 7489 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
7509 Handle<JSObject> holder(lookup.holder()); 7490 Handle<JSObject> holder(lookup.holder());
7510 Handle<Map> holder_map(holder->map()); 7491 Handle<Map> holder_map(holder->map());
7511 AddCheckMap(object, map); 7492 AddCheckMap(object, map);
7512 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone())); 7493 AddInstruction(new(zone()) HCheckPrototypeMaps(prototype, holder, zone()));
7513 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); 7494 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map));
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
7757 // it's a keyed property) and registered in the full codegen. 7738 // it's a keyed property) and registered in the full codegen.
7758 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); 7739 HBasicBlock* if_jsarray = graph()->CreateBasicBlock();
7759 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); 7740 HBasicBlock* if_fastobject = graph()->CreateBasicBlock();
7760 HHasInstanceTypeAndBranch* typecheck = 7741 HHasInstanceTypeAndBranch* typecheck =
7761 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); 7742 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
7762 typecheck->SetSuccessorAt(0, if_jsarray); 7743 typecheck->SetSuccessorAt(0, if_jsarray);
7763 typecheck->SetSuccessorAt(1, if_fastobject); 7744 typecheck->SetSuccessorAt(1, if_fastobject);
7764 current_block()->Finish(typecheck); 7745 current_block()->Finish(typecheck);
7765 7746
7766 set_current_block(if_jsarray); 7747 set_current_block(if_jsarray);
7767 HInstruction* length; 7748 HInstruction* length = AddInstruction(new(zone())
7768 length = AddInstruction( 7749 HLoadNamedField(object, AccessArrayLength(), typecheck));
7769 HLoadNamedField::NewArrayLength(zone(), object, typecheck, 7750 length->set_type(HType::Smi());
7770 HType::Smi())); 7751
7771 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); 7752 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY);
7772 access = AddInstruction(BuildFastElementAccess( 7753 access = AddInstruction(BuildFastElementAccess(
7773 elements, checked_key, val, elements_kind_branch, 7754 elements, checked_key, val, elements_kind_branch,
7774 elements_kind, is_store, STANDARD_STORE)); 7755 elements_kind, is_store, STANDARD_STORE));
7775 if (!is_store) { 7756 if (!is_store) {
7776 Push(access); 7757 Push(access);
7777 } 7758 }
7778 7759
7779 *has_side_effects |= access->HasObservableSideEffects(); 7760 *has_side_effects |= access->HasObservableSideEffects();
7780 // The caller will use has_side_effects and add correct Simulate. 7761 // The caller will use has_side_effects and add correct Simulate.
(...skipping 2633 matching lines...) Expand 10 before | Expand all | Expand 10 after
10414 Handle<Object> value = 10395 Handle<Object> value =
10415 Handle<Object>(boilerplate_object->InObjectPropertyAt(i), 10396 Handle<Object>(boilerplate_object->InObjectPropertyAt(i),
10416 isolate()); 10397 isolate());
10417 if (value->IsJSObject()) { 10398 if (value->IsJSObject()) {
10418 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 10399 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
10419 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 10400 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
10420 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), 10401 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i),
10421 isolate())); 10402 isolate()));
10422 HInstruction* value_instruction = 10403 HInstruction* value_instruction =
10423 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); 10404 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset));
10424 AddInstruction(new(zone) HStoreNamedField( 10405
10425 object_properties, factory->unknown_field_string(), value_instruction, 10406 ObjectAccess access = AccessInobject(factory->unknown_field_string(),
10426 true, boilerplate_object->GetInObjectPropertyOffset(i))); 10407 boilerplate_object->GetInObjectPropertyOffset(i));
10408 AddStore(object_properties, access, value_instruction);
10409
10427 BuildEmitDeepCopy(value_object, original_value_object, target, 10410 BuildEmitDeepCopy(value_object, original_value_object, target,
10428 offset, DONT_TRACK_ALLOCATION_SITE); 10411 offset, DONT_TRACK_ALLOCATION_SITE);
10429 } else { 10412 } else {
10430 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( 10413 HInstruction* value_instruction = AddInstruction(new(zone) HConstant(
10431 value, Representation::Tagged())); 10414 value, Representation::Tagged()));
10432 AddInstruction(new(zone) HStoreNamedField( 10415
10433 object_properties, factory->unknown_field_string(), value_instruction, 10416 ObjectAccess access = AccessInobject(factory->unknown_field_string(),
10434 true, boilerplate_object->GetInObjectPropertyOffset(i))); 10417 boilerplate_object->GetInObjectPropertyOffset(i));
10418 AddStore(object_properties, access, value_instruction);
10435 } 10419 }
10436 } 10420 }
10437 10421
10438 // Build Allocation Site Info if desired 10422 // Build Allocation Site Info if desired
10439 if (create_allocation_site_info) { 10423 if (create_allocation_site_info) {
10440 HValue* alloc_site = 10424 HValue* alloc_site =
10441 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize)); 10425 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize));
10442 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); 10426 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
10443 BuildStoreMap(alloc_site, alloc_site_map); 10427 HValue* alloc_site_map_constant = AddInstruction(new(zone)
10444 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; 10428 HConstant(alloc_site_map, Representation::Tagged()));
10445 AddInstruction(new(zone) HStoreNamedField(alloc_site, 10429 AddStore(alloc_site, AccessMap(), alloc_site_map_constant);
10446 factory->payload_string(), 10430 ObjectAccess access = AccessInobject(
10447 original_boilerplate, 10431 factory->payload_string(), AllocationSiteInfo::kPayloadOffset);
10448 true, alloc_payload_offset)); 10432 AddStore(alloc_site, access, original_boilerplate);
10449 } 10433 }
10450 10434
10451 if (object_elements != NULL) { 10435 if (object_elements != NULL) {
10452 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( 10436 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant(
10453 elements, Representation::Tagged())); 10437 elements, Representation::Tagged()));
10454 10438
10455 int elements_length = elements->length(); 10439 int elements_length = elements->length();
10456 HValue* object_elements_length = 10440 HValue* object_elements_length =
10457 AddInstruction(new(zone) HConstant( 10441 AddInstruction(new(zone) HConstant(
10458 elements_length, Representation::Integer32())); 10442 elements_length, Representation::Integer32()));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
10510 int elements_offset, 10494 int elements_offset,
10511 int elements_size) { 10495 int elements_size) {
10512 ASSERT(boilerplate_object->properties()->length() == 0); 10496 ASSERT(boilerplate_object->properties()->length() == 0);
10513 Zone* zone = this->zone(); 10497 Zone* zone = this->zone();
10514 Factory* factory = isolate()->factory(); 10498 Factory* factory = isolate()->factory();
10515 HValue* result = NULL; 10499 HValue* result = NULL;
10516 10500
10517 HValue* object_header = 10501 HValue* object_header =
10518 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); 10502 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset));
10519 Handle<Map> boilerplate_object_map(boilerplate_object->map()); 10503 Handle<Map> boilerplate_object_map(boilerplate_object->map());
10520 BuildStoreMap(object_header, boilerplate_object_map); 10504 HValue* boilerplate_object_map_constant = AddInstruction(new(zone)
10505 HConstant(boilerplate_object_map, Representation::Tagged()));
10506 AddStore(object_header, AccessMap(), boilerplate_object_map_constant);
10521 10507
10522 HInstruction* elements; 10508 HInstruction* elements;
10523 if (elements_size == 0) { 10509 if (elements_size == 0) {
10524 Handle<Object> elements_field = 10510 Handle<Object> elements_field =
10525 Handle<Object>(boilerplate_object->elements(), isolate()); 10511 Handle<Object>(boilerplate_object->elements(), isolate());
10526 elements = AddInstruction(new(zone) HConstant( 10512 elements = AddInstruction(new(zone) HConstant(
10527 elements_field, Representation::Tagged())); 10513 elements_field, Representation::Tagged()));
10528 } else { 10514 } else {
10529 elements = AddInstruction(new(zone) HInnerAllocatedObject( 10515 elements = AddInstruction(new(zone) HInnerAllocatedObject(
10530 target, elements_offset)); 10516 target, elements_offset));
10531 result = elements; 10517 result = elements;
10532 } 10518 }
10533 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( 10519 AddStore(object_header, AccessElements(), elements);
10534 object_header,
10535 factory->elements_field_string(),
10536 elements,
10537 true, JSObject::kElementsOffset));
10538 elements_store->SetGVNFlag(kChangesElementsPointer);
10539 10520
10540 Handle<Object> properties_field = 10521 Handle<Object> properties_field =
10541 Handle<Object>(boilerplate_object->properties(), isolate()); 10522 Handle<Object>(boilerplate_object->properties(), isolate());
10542 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 10523 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
10543 HInstruction* properties = AddInstruction(new(zone) HConstant( 10524 HInstruction* properties = AddInstruction(new(zone) HConstant(
10544 properties_field, Representation::None())); 10525 properties_field, Representation::None()));
10545 AddInstruction(new(zone) HStoreNamedField(object_header, 10526 ObjectAccess access = AccessInobject(
10546 factory->empty_string(), 10527 factory->empty_string(), JSObject::kPropertiesOffset);
10547 properties, 10528 AddStore(object_header, access, properties);
10548 true, JSObject::kPropertiesOffset));
10549 10529
10550 if (boilerplate_object->IsJSArray()) { 10530 if (boilerplate_object->IsJSArray()) {
10551 Handle<JSArray> boilerplate_array = 10531 Handle<JSArray> boilerplate_array =
10552 Handle<JSArray>::cast(boilerplate_object); 10532 Handle<JSArray>::cast(boilerplate_object);
10553 Handle<Object> length_field = 10533 Handle<Object> length_field =
10554 Handle<Object>(boilerplate_array->length(), isolate()); 10534 Handle<Object>(boilerplate_array->length(), isolate());
10555 HInstruction* length = AddInstruction(new(zone) HConstant( 10535 HInstruction* length = AddInstruction(new(zone) HConstant(
10556 length_field, Representation::None())); 10536 length_field, Representation::None()));
10557 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( 10537 AddStore(object_header, AccessArrayLength(), length);
10558 object_header,
10559 factory->length_field_string(),
10560 length,
10561 true, JSArray::kLengthOffset));
10562 length_store->SetGVNFlag(kChangesArrayLengths);
10563 } 10538 }
10564 10539
10565 return result; 10540 return result;
10566 } 10541 }
10567 10542
10568 10543
10569 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { 10544 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) {
10570 ASSERT(!HasStackOverflow()); 10545 ASSERT(!HasStackOverflow());
10571 ASSERT(current_block() != NULL); 10546 ASSERT(current_block() != NULL);
10572 ASSERT(current_block()->HasPredecessor()); 10547 ASSERT(current_block()->HasPredecessor());
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
10940 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); 10915 HBasicBlock* if_js_value = graph()->CreateBasicBlock();
10941 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); 10916 HBasicBlock* not_js_value = graph()->CreateBasicBlock();
10942 typecheck->SetSuccessorAt(0, if_js_value); 10917 typecheck->SetSuccessorAt(0, if_js_value);
10943 typecheck->SetSuccessorAt(1, not_js_value); 10918 typecheck->SetSuccessorAt(1, not_js_value);
10944 current_block()->Finish(typecheck); 10919 current_block()->Finish(typecheck);
10945 not_js_value->Goto(join); 10920 not_js_value->Goto(join);
10946 10921
10947 // Create in-object property store to kValueOffset. 10922 // Create in-object property store to kValueOffset.
10948 set_current_block(if_js_value); 10923 set_current_block(if_js_value);
10949 Handle<String> name = isolate()->factory()->undefined_string(); 10924 Handle<String> name = isolate()->factory()->undefined_string();
10950 AddInstruction(new(zone()) HStoreNamedField(object, 10925 AddStore(object, AccessInobject(name, JSValue::kValueOffset), value);
10951 name,
10952 value,
10953 true, // in-object store.
10954 JSValue::kValueOffset));
10955 if_js_value->Goto(join); 10926 if_js_value->Goto(join);
10956 join->SetJoinId(call->id()); 10927 join->SetJoinId(call->id());
10957 set_current_block(join); 10928 set_current_block(join);
10958 return ast_context()->ReturnValue(value); 10929 return ast_context()->ReturnValue(value);
10959 } 10930 }
10960 10931
10961 10932
10962 // Fast support for charCodeAt(n). 10933 // Fast support for charCodeAt(n).
10963 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 10934 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
10964 ASSERT(call->arguments()->length() == 2); 10935 ASSERT(call->arguments()->length() == 2);
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
11919 } 11890 }
11920 } 11891 }
11921 11892
11922 #ifdef DEBUG 11893 #ifdef DEBUG
11923 if (graph_ != NULL) graph_->Verify(false); // No full verify. 11894 if (graph_ != NULL) graph_->Verify(false); // No full verify.
11924 if (allocator_ != NULL) allocator_->Verify(); 11895 if (allocator_ != NULL) allocator_->Verify();
11925 #endif 11896 #endif
11926 } 11897 }
11927 11898
11928 } } // namespace v8::internal 11899 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698