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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 6759025: Version 3.2.6 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 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
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/ic.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 // Check that receiver is a JSObject. 132 // Check that receiver is a JSObject.
133 __ CmpInstanceType(r0, FIRST_JS_OBJECT_TYPE); 133 __ CmpInstanceType(r0, FIRST_JS_OBJECT_TYPE);
134 __ j(below, miss_label, not_taken); 134 __ j(below, miss_label, not_taken);
135 135
136 // Load properties array. 136 // Load properties array.
137 Register properties = r0; 137 Register properties = r0;
138 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); 138 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
139 139
140 // Check that the properties array is a dictionary. 140 // Check that the properties array is a dictionary.
141 __ cmp(FieldOperand(properties, HeapObject::kMapOffset), 141 __ cmp(FieldOperand(properties, HeapObject::kMapOffset),
142 Immediate(FACTORY->hash_table_map())); 142 Immediate(masm->isolate()->factory()->hash_table_map()));
143 __ j(not_equal, miss_label); 143 __ j(not_equal, miss_label);
144 144
145 // Compute the capacity mask. 145 // Compute the capacity mask.
146 const int kCapacityOffset = 146 const int kCapacityOffset =
147 StringDictionary::kHeaderSize + 147 StringDictionary::kHeaderSize +
148 StringDictionary::kCapacityIndex * kPointerSize; 148 StringDictionary::kCapacityIndex * kPointerSize;
149 149
150 // Generate an unrolled loop that performs a few probes before 150 // Generate an unrolled loop that performs a few probes before
151 // giving up. 151 // giving up.
152 static const int kProbes = 4; 152 static const int kProbes = 4;
(...skipping 19 matching lines...) Expand all
172 172
173 // Scale the index by multiplying by the entry size. 173 // Scale the index by multiplying by the entry size.
174 ASSERT(StringDictionary::kEntrySize == 3); 174 ASSERT(StringDictionary::kEntrySize == 3);
175 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. 175 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3.
176 176
177 Register entity_name = r1; 177 Register entity_name = r1;
178 // Having undefined at this place means the name is not contained. 178 // Having undefined at this place means the name is not contained.
179 ASSERT_EQ(kSmiTagSize, 1); 179 ASSERT_EQ(kSmiTagSize, 1);
180 __ mov(entity_name, Operand(properties, index, times_half_pointer_size, 180 __ mov(entity_name, Operand(properties, index, times_half_pointer_size,
181 kElementsStartOffset - kHeapObjectTag)); 181 kElementsStartOffset - kHeapObjectTag));
182 __ cmp(entity_name, FACTORY->undefined_value()); 182 __ cmp(entity_name, masm->isolate()->factory()->undefined_value());
183 if (i != kProbes - 1) { 183 if (i != kProbes - 1) {
184 __ j(equal, &done, taken); 184 __ j(equal, &done, taken);
185 185
186 // Stop if found the property. 186 // Stop if found the property.
187 __ cmp(entity_name, Handle<String>(name)); 187 __ cmp(entity_name, Handle<String>(name));
188 __ j(equal, miss_label, not_taken); 188 __ j(equal, miss_label, not_taken);
189 189
190 // Check if the entry name is not a symbol. 190 // Check if the entry name is not a symbol.
191 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); 191 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset));
192 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset), 192 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset),
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 Label* miss) { 853 Label* miss) {
854 Object* probe; 854 Object* probe;
855 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); 855 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name);
856 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 856 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
857 } 857 }
858 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); 858 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
859 ASSERT(cell->value()->IsTheHole()); 859 ASSERT(cell->value()->IsTheHole());
860 if (Serializer::enabled()) { 860 if (Serializer::enabled()) {
861 __ mov(scratch, Immediate(Handle<Object>(cell))); 861 __ mov(scratch, Immediate(Handle<Object>(cell)));
862 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), 862 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
863 Immediate(FACTORY->the_hole_value())); 863 Immediate(masm->isolate()->factory()->the_hole_value()));
864 } else { 864 } else {
865 __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)), 865 __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)),
866 Immediate(FACTORY->the_hole_value())); 866 Immediate(masm->isolate()->factory()->the_hole_value()));
867 } 867 }
868 __ j(not_equal, miss, not_taken); 868 __ j(not_equal, miss, not_taken);
869 return cell; 869 return cell;
870 } 870 }
871 871
872 872
873 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 873 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
874 // from object to (but not including) holder. 874 // from object to (but not including) holder.
875 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( 875 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells(
876 MacroAssembler* masm, 876 MacroAssembler* masm,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 Register scratch1, 909 Register scratch1,
910 Register scratch2, 910 Register scratch2,
911 String* name, 911 String* name,
912 int save_at_depth, 912 int save_at_depth,
913 Label* miss) { 913 Label* miss) {
914 // Make sure there's no overlap between holder and object registers. 914 // Make sure there's no overlap between holder and object registers.
915 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 915 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
916 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 916 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
917 && !scratch2.is(scratch1)); 917 && !scratch2.is(scratch1));
918 918
919 Heap* heap = isolate()->heap();
920
921 // Keep track of the current object in register reg. 919 // Keep track of the current object in register reg.
922 Register reg = object_reg; 920 Register reg = object_reg;
923 JSObject* current = object; 921 JSObject* current = object;
924 int depth = 0; 922 int depth = 0;
925 923
926 if (save_at_depth == depth) { 924 if (save_at_depth == depth) {
927 __ mov(Operand(esp, kPointerSize), reg); 925 __ mov(Operand(esp, kPointerSize), reg);
928 } 926 }
929 927
930 // Traverse the prototype chain and check the maps in the prototype chain for 928 // Traverse the prototype chain and check the maps in the prototype chain for
931 // fast and global objects or do negative lookup for normal objects. 929 // fast and global objects or do negative lookup for normal objects.
932 while (current != holder) { 930 while (current != holder) {
933 depth++; 931 depth++;
934 932
935 // Only global objects and objects that do not require access 933 // Only global objects and objects that do not require access
936 // checks are allowed in stubs. 934 // checks are allowed in stubs.
937 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); 935 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
938 936
939 ASSERT(current->GetPrototype()->IsJSObject()); 937 ASSERT(current->GetPrototype()->IsJSObject());
940 JSObject* prototype = JSObject::cast(current->GetPrototype()); 938 JSObject* prototype = JSObject::cast(current->GetPrototype());
941 if (!current->HasFastProperties() && 939 if (!current->HasFastProperties() &&
942 !current->IsJSGlobalObject() && 940 !current->IsJSGlobalObject() &&
943 !current->IsJSGlobalProxy()) { 941 !current->IsJSGlobalProxy()) {
944 if (!name->IsSymbol()) { 942 if (!name->IsSymbol()) {
945 MaybeObject* maybe_lookup_result = heap->LookupSymbol(name); 943 MaybeObject* maybe_lookup_result = heap()->LookupSymbol(name);
946 Object* lookup_result = NULL; // Initialization to please compiler. 944 Object* lookup_result = NULL; // Initialization to please compiler.
947 if (!maybe_lookup_result->ToObject(&lookup_result)) { 945 if (!maybe_lookup_result->ToObject(&lookup_result)) {
948 set_failure(Failure::cast(maybe_lookup_result)); 946 set_failure(Failure::cast(maybe_lookup_result));
949 return reg; 947 return reg;
950 } 948 }
951 name = String::cast(lookup_result); 949 name = String::cast(lookup_result);
952 } 950 }
953 ASSERT(current->property_dictionary()->FindEntry(name) == 951 ASSERT(current->property_dictionary()->FindEntry(name) ==
954 StringDictionary::kNotFound); 952 StringDictionary::kNotFound);
955 953
956 GenerateDictionaryNegativeLookup(masm(), 954 GenerateDictionaryNegativeLookup(masm(),
957 miss, 955 miss,
958 reg, 956 reg,
959 name, 957 name,
960 scratch1, 958 scratch1,
961 scratch2); 959 scratch2);
962 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 960 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
963 reg = holder_reg; // from now the object is in holder_reg 961 reg = holder_reg; // from now the object is in holder_reg
964 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 962 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
965 } else if (heap->InNewSpace(prototype)) { 963 } else if (heap()->InNewSpace(prototype)) {
966 // Get the map of the current object. 964 // Get the map of the current object.
967 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 965 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
968 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map()))); 966 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map())));
969 // Branch on the result of the map check. 967 // Branch on the result of the map check.
970 __ j(not_equal, miss, not_taken); 968 __ j(not_equal, miss, not_taken);
971 // Check access rights to the global object. This has to happen 969 // Check access rights to the global object. This has to happen
972 // after the map check so that we know that the object is 970 // after the map check so that we know that the object is
973 // actually a global object. 971 // actually a global object.
974 if (current->IsJSGlobalProxy()) { 972 if (current->IsJSGlobalProxy()) {
975 __ CheckAccessGlobalProxy(reg, scratch1, miss); 973 __ CheckAccessGlobalProxy(reg, scratch1, miss);
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 // of this method.) 1207 // of this method.)
1210 CompileCallLoadPropertyWithInterceptor(masm(), 1208 CompileCallLoadPropertyWithInterceptor(masm(),
1211 receiver, 1209 receiver,
1212 holder_reg, 1210 holder_reg,
1213 name_reg, 1211 name_reg,
1214 interceptor_holder); 1212 interceptor_holder);
1215 1213
1216 // Check if interceptor provided a value for property. If it's 1214 // Check if interceptor provided a value for property. If it's
1217 // the case, return immediately. 1215 // the case, return immediately.
1218 Label interceptor_failed; 1216 Label interceptor_failed;
1219 __ cmp(eax, FACTORY->no_interceptor_result_sentinel()); 1217 __ cmp(eax, factory()->no_interceptor_result_sentinel());
1220 __ j(equal, &interceptor_failed); 1218 __ j(equal, &interceptor_failed);
1221 __ LeaveInternalFrame(); 1219 __ LeaveInternalFrame();
1222 __ ret(0); 1220 __ ret(0);
1223 1221
1224 __ bind(&interceptor_failed); 1222 __ bind(&interceptor_failed);
1225 __ pop(name_reg); 1223 __ pop(name_reg);
1226 __ pop(holder_reg); 1224 __ pop(holder_reg);
1227 if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) { 1225 if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
1228 __ pop(receiver); 1226 __ pop(receiver);
1229 } 1227 }
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1467 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1465 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1468 __ ret((argc + 1) * kPointerSize); 1466 __ ret((argc + 1) * kPointerSize);
1469 } else { 1467 } else {
1470 Label call_builtin; 1468 Label call_builtin;
1471 1469
1472 // Get the elements array of the object. 1470 // Get the elements array of the object.
1473 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1471 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1474 1472
1475 // Check that the elements are in fast mode and writable. 1473 // Check that the elements are in fast mode and writable.
1476 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1474 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1477 Immediate(FACTORY->fixed_array_map())); 1475 Immediate(factory()->fixed_array_map()));
1478 __ j(not_equal, &call_builtin); 1476 __ j(not_equal, &call_builtin);
1479 1477
1480 if (argc == 1) { // Otherwise fall through to call builtin. 1478 if (argc == 1) { // Otherwise fall through to call builtin.
1481 Label exit, with_write_barrier, attempt_to_grow_elements; 1479 Label exit, with_write_barrier, attempt_to_grow_elements;
1482 1480
1483 // Get the array's length into eax and calculate new length. 1481 // Get the array's length into eax and calculate new length.
1484 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1482 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1485 STATIC_ASSERT(kSmiTagSize == 1); 1483 STATIC_ASSERT(kSmiTagSize == 1);
1486 STATIC_ASSERT(kSmiTag == 0); 1484 STATIC_ASSERT(kSmiTag == 0);
1487 __ add(Operand(eax), Immediate(Smi::FromInt(argc))); 1485 __ add(Operand(eax), Immediate(Smi::FromInt(argc)));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1543 1541
1544 // We fit and could grow elements. 1542 // We fit and could grow elements.
1545 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx); 1543 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
1546 __ mov(ecx, Operand(esp, argc * kPointerSize)); 1544 __ mov(ecx, Operand(esp, argc * kPointerSize));
1547 1545
1548 // Push the argument... 1546 // Push the argument...
1549 __ mov(Operand(edx, 0), ecx); 1547 __ mov(Operand(edx, 0), ecx);
1550 // ... and fill the rest with holes. 1548 // ... and fill the rest with holes.
1551 for (int i = 1; i < kAllocationDelta; i++) { 1549 for (int i = 1; i < kAllocationDelta; i++) {
1552 __ mov(Operand(edx, i * kPointerSize), 1550 __ mov(Operand(edx, i * kPointerSize),
1553 Immediate(FACTORY->the_hole_value())); 1551 Immediate(factory()->the_hole_value()));
1554 } 1552 }
1555 1553
1556 // Restore receiver to edx as finish sequence assumes it's here. 1554 // Restore receiver to edx as finish sequence assumes it's here.
1557 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1555 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1558 1556
1559 // Increment element's and array's sizes. 1557 // Increment element's and array's sizes.
1560 __ add(FieldOperand(ebx, FixedArray::kLengthOffset), 1558 __ add(FieldOperand(ebx, FixedArray::kLengthOffset),
1561 Immediate(Smi::FromInt(kAllocationDelta))); 1559 Immediate(Smi::FromInt(kAllocationDelta)));
1562 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); 1560 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1563 1561
(...skipping 25 matching lines...) Expand all
1589 // ----------- S t a t e ------------- 1587 // ----------- S t a t e -------------
1590 // -- ecx : name 1588 // -- ecx : name
1591 // -- esp[0] : return address 1589 // -- esp[0] : return address
1592 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1590 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1593 // -- ... 1591 // -- ...
1594 // -- esp[(argc + 1) * 4] : receiver 1592 // -- esp[(argc + 1) * 4] : receiver
1595 // ----------------------------------- 1593 // -----------------------------------
1596 1594
1597 // If object is not an array, bail out to regular call. 1595 // If object is not an array, bail out to regular call.
1598 if (!object->IsJSArray() || cell != NULL) { 1596 if (!object->IsJSArray() || cell != NULL) {
1599 return isolate()->heap()->undefined_value(); 1597 return heap()->undefined_value();
1600 } 1598 }
1601 1599
1602 Label miss, return_undefined, call_builtin; 1600 Label miss, return_undefined, call_builtin;
1603 1601
1604 GenerateNameCheck(name, &miss); 1602 GenerateNameCheck(name, &miss);
1605 1603
1606 // Get the receiver from the stack. 1604 // Get the receiver from the stack.
1607 const int argc = arguments().immediate(); 1605 const int argc = arguments().immediate();
1608 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1606 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1609 1607
1610 // Check that the receiver isn't a smi. 1608 // Check that the receiver isn't a smi.
1611 __ test(edx, Immediate(kSmiTagMask)); 1609 __ test(edx, Immediate(kSmiTagMask));
1612 __ j(zero, &miss); 1610 __ j(zero, &miss);
1613 CheckPrototypes(JSObject::cast(object), edx, 1611 CheckPrototypes(JSObject::cast(object), edx,
1614 holder, ebx, 1612 holder, ebx,
1615 eax, edi, name, &miss); 1613 eax, edi, name, &miss);
1616 1614
1617 // Get the elements array of the object. 1615 // Get the elements array of the object.
1618 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1616 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1619 1617
1620 // Check that the elements are in fast mode and writable. 1618 // Check that the elements are in fast mode and writable.
1621 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1619 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1622 Immediate(FACTORY->fixed_array_map())); 1620 Immediate(factory()->fixed_array_map()));
1623 __ j(not_equal, &call_builtin); 1621 __ j(not_equal, &call_builtin);
1624 1622
1625 // Get the array's length into ecx and calculate new length. 1623 // Get the array's length into ecx and calculate new length.
1626 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset)); 1624 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset));
1627 __ sub(Operand(ecx), Immediate(Smi::FromInt(1))); 1625 __ sub(Operand(ecx), Immediate(Smi::FromInt(1)));
1628 __ j(negative, &return_undefined); 1626 __ j(negative, &return_undefined);
1629 1627
1630 // Get the last element. 1628 // Get the last element.
1631 STATIC_ASSERT(kSmiTagSize == 1); 1629 STATIC_ASSERT(kSmiTagSize == 1);
1632 STATIC_ASSERT(kSmiTag == 0); 1630 STATIC_ASSERT(kSmiTag == 0);
1633 __ mov(eax, FieldOperand(ebx, 1631 __ mov(eax, FieldOperand(ebx,
1634 ecx, times_half_pointer_size, 1632 ecx, times_half_pointer_size,
1635 FixedArray::kHeaderSize)); 1633 FixedArray::kHeaderSize));
1636 __ cmp(Operand(eax), Immediate(FACTORY->the_hole_value())); 1634 __ cmp(Operand(eax), Immediate(factory()->the_hole_value()));
1637 __ j(equal, &call_builtin); 1635 __ j(equal, &call_builtin);
1638 1636
1639 // Set the array's length. 1637 // Set the array's length.
1640 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx); 1638 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx);
1641 1639
1642 // Fill with the hole. 1640 // Fill with the hole.
1643 __ mov(FieldOperand(ebx, 1641 __ mov(FieldOperand(ebx,
1644 ecx, times_half_pointer_size, 1642 ecx, times_half_pointer_size,
1645 FixedArray::kHeaderSize), 1643 FixedArray::kHeaderSize),
1646 Immediate(FACTORY->the_hole_value())); 1644 Immediate(factory()->the_hole_value()));
1647 __ ret((argc + 1) * kPointerSize); 1645 __ ret((argc + 1) * kPointerSize);
1648 1646
1649 __ bind(&return_undefined); 1647 __ bind(&return_undefined);
1650 __ mov(eax, Immediate(FACTORY->undefined_value())); 1648 __ mov(eax, Immediate(factory()->undefined_value()));
1651 __ ret((argc + 1) * kPointerSize); 1649 __ ret((argc + 1) * kPointerSize);
1652 1650
1653 __ bind(&call_builtin); 1651 __ bind(&call_builtin);
1654 __ TailCallExternalReference( 1652 __ TailCallExternalReference(
1655 ExternalReference(Builtins::c_ArrayPop, isolate()), 1653 ExternalReference(Builtins::c_ArrayPop, isolate()),
1656 argc + 1, 1654 argc + 1,
1657 1); 1655 1);
1658 1656
1659 __ bind(&miss); 1657 __ bind(&miss);
1660 MaybeObject* maybe_result = GenerateMissBranch(); 1658 MaybeObject* maybe_result = GenerateMissBranch();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 ebx, edx, edi, name, &miss); 1705 ebx, edx, edi, name, &miss);
1708 1706
1709 Register receiver = ebx; 1707 Register receiver = ebx;
1710 Register index = edi; 1708 Register index = edi;
1711 Register scratch = edx; 1709 Register scratch = edx;
1712 Register result = eax; 1710 Register result = eax;
1713 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 1711 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
1714 if (argc > 0) { 1712 if (argc > 0) {
1715 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 1713 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
1716 } else { 1714 } else {
1717 __ Set(index, Immediate(FACTORY->undefined_value())); 1715 __ Set(index, Immediate(factory()->undefined_value()));
1718 } 1716 }
1719 1717
1720 StringCharCodeAtGenerator char_code_at_generator(receiver, 1718 StringCharCodeAtGenerator char_code_at_generator(receiver,
1721 index, 1719 index,
1722 scratch, 1720 scratch,
1723 result, 1721 result,
1724 &miss, // When not a string. 1722 &miss, // When not a string.
1725 &miss, // When not a number. 1723 &miss, // When not a number.
1726 index_out_of_range_label, 1724 index_out_of_range_label,
1727 STRING_INDEX_IS_NUMBER); 1725 STRING_INDEX_IS_NUMBER);
1728 char_code_at_generator.GenerateFast(masm()); 1726 char_code_at_generator.GenerateFast(masm());
1729 __ ret((argc + 1) * kPointerSize); 1727 __ ret((argc + 1) * kPointerSize);
1730 1728
1731 StubRuntimeCallHelper call_helper; 1729 StubRuntimeCallHelper call_helper;
1732 char_code_at_generator.GenerateSlow(masm(), call_helper); 1730 char_code_at_generator.GenerateSlow(masm(), call_helper);
1733 1731
1734 if (index_out_of_range.is_linked()) { 1732 if (index_out_of_range.is_linked()) {
1735 __ bind(&index_out_of_range); 1733 __ bind(&index_out_of_range);
1736 __ Set(eax, Immediate(FACTORY->nan_value())); 1734 __ Set(eax, Immediate(factory()->nan_value()));
1737 __ ret((argc + 1) * kPointerSize); 1735 __ ret((argc + 1) * kPointerSize);
1738 } 1736 }
1739 1737
1740 __ bind(&miss); 1738 __ bind(&miss);
1741 // Restore function name in ecx. 1739 // Restore function name in ecx.
1742 __ Set(ecx, Immediate(Handle<String>(name))); 1740 __ Set(ecx, Immediate(Handle<String>(name)));
1743 __ bind(&name_miss); 1741 __ bind(&name_miss);
1744 MaybeObject* maybe_result = GenerateMissBranch(); 1742 MaybeObject* maybe_result = GenerateMissBranch();
1745 if (maybe_result->IsFailure()) return maybe_result; 1743 if (maybe_result->IsFailure()) return maybe_result;
1746 1744
(...skipping 11 matching lines...) Expand all
1758 // ----------- S t a t e ------------- 1756 // ----------- S t a t e -------------
1759 // -- ecx : function name 1757 // -- ecx : function name
1760 // -- esp[0] : return address 1758 // -- esp[0] : return address
1761 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1759 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1762 // -- ... 1760 // -- ...
1763 // -- esp[(argc + 1) * 4] : receiver 1761 // -- esp[(argc + 1) * 4] : receiver
1764 // ----------------------------------- 1762 // -----------------------------------
1765 1763
1766 // If object is not a string, bail out to regular call. 1764 // If object is not a string, bail out to regular call.
1767 if (!object->IsString() || cell != NULL) { 1765 if (!object->IsString() || cell != NULL) {
1768 return isolate()->heap()->undefined_value(); 1766 return heap()->undefined_value();
1769 } 1767 }
1770 1768
1771 const int argc = arguments().immediate(); 1769 const int argc = arguments().immediate();
1772 1770
1773 Label miss; 1771 Label miss;
1774 Label name_miss; 1772 Label name_miss;
1775 Label index_out_of_range; 1773 Label index_out_of_range;
1776 Label* index_out_of_range_label = &index_out_of_range; 1774 Label* index_out_of_range_label = &index_out_of_range;
1777 1775
1778 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { 1776 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) {
(...skipping 13 matching lines...) Expand all
1792 1790
1793 Register receiver = eax; 1791 Register receiver = eax;
1794 Register index = edi; 1792 Register index = edi;
1795 Register scratch1 = ebx; 1793 Register scratch1 = ebx;
1796 Register scratch2 = edx; 1794 Register scratch2 = edx;
1797 Register result = eax; 1795 Register result = eax;
1798 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 1796 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
1799 if (argc > 0) { 1797 if (argc > 0) {
1800 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 1798 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
1801 } else { 1799 } else {
1802 __ Set(index, Immediate(FACTORY->undefined_value())); 1800 __ Set(index, Immediate(factory()->undefined_value()));
1803 } 1801 }
1804 1802
1805 StringCharAtGenerator char_at_generator(receiver, 1803 StringCharAtGenerator char_at_generator(receiver,
1806 index, 1804 index,
1807 scratch1, 1805 scratch1,
1808 scratch2, 1806 scratch2,
1809 result, 1807 result,
1810 &miss, // When not a string. 1808 &miss, // When not a string.
1811 &miss, // When not a number. 1809 &miss, // When not a number.
1812 index_out_of_range_label, 1810 index_out_of_range_label,
1813 STRING_INDEX_IS_NUMBER); 1811 STRING_INDEX_IS_NUMBER);
1814 char_at_generator.GenerateFast(masm()); 1812 char_at_generator.GenerateFast(masm());
1815 __ ret((argc + 1) * kPointerSize); 1813 __ ret((argc + 1) * kPointerSize);
1816 1814
1817 StubRuntimeCallHelper call_helper; 1815 StubRuntimeCallHelper call_helper;
1818 char_at_generator.GenerateSlow(masm(), call_helper); 1816 char_at_generator.GenerateSlow(masm(), call_helper);
1819 1817
1820 if (index_out_of_range.is_linked()) { 1818 if (index_out_of_range.is_linked()) {
1821 __ bind(&index_out_of_range); 1819 __ bind(&index_out_of_range);
1822 __ Set(eax, Immediate(FACTORY->empty_string())); 1820 __ Set(eax, Immediate(factory()->empty_string()));
1823 __ ret((argc + 1) * kPointerSize); 1821 __ ret((argc + 1) * kPointerSize);
1824 } 1822 }
1825 1823
1826 __ bind(&miss); 1824 __ bind(&miss);
1827 // Restore function name in ecx. 1825 // Restore function name in ecx.
1828 __ Set(ecx, Immediate(Handle<String>(name))); 1826 __ Set(ecx, Immediate(Handle<String>(name)));
1829 __ bind(&name_miss); 1827 __ bind(&name_miss);
1830 MaybeObject* maybe_result = GenerateMissBranch(); 1828 MaybeObject* maybe_result = GenerateMissBranch();
1831 if (maybe_result->IsFailure()) return maybe_result; 1829 if (maybe_result->IsFailure()) return maybe_result;
1832 1830
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1916 JSFunction* function, 1914 JSFunction* function,
1917 String* name) { 1915 String* name) {
1918 // ----------- S t a t e ------------- 1916 // ----------- S t a t e -------------
1919 // -- ecx : name 1917 // -- ecx : name
1920 // -- esp[0] : return address 1918 // -- esp[0] : return address
1921 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1919 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1922 // -- ... 1920 // -- ...
1923 // -- esp[(argc + 1) * 4] : receiver 1921 // -- esp[(argc + 1) * 4] : receiver
1924 // ----------------------------------- 1922 // -----------------------------------
1925 1923
1926 if (isolate()->cpu_features()->IsSupported(SSE2)) { 1924 if (!isolate()->cpu_features()->IsSupported(SSE2)) {
1927 return isolate()->heap()->undefined_value(); 1925 return isolate()->heap()->undefined_value();
1928 } 1926 }
1929 1927
1930 CpuFeatures::Scope use_sse2(SSE2); 1928 CpuFeatures::Scope use_sse2(SSE2);
1931 1929
1932 const int argc = arguments().immediate(); 1930 const int argc = arguments().immediate();
1933 1931
1934 // If the object is not a JSObject or we got an unexpected number of 1932 // If the object is not a JSObject or we got an unexpected number of
1935 // arguments, bail out to the regular call. 1933 // arguments, bail out to the regular call.
1936 if (!object->IsJSObject() || argc != 1) { 1934 if (!object->IsJSObject() || argc != 1) {
(...skipping 22 matching lines...) Expand all
1959 __ mov(eax, Operand(esp, 1 * kPointerSize)); 1957 __ mov(eax, Operand(esp, 1 * kPointerSize));
1960 1958
1961 // Check if the argument is a smi. 1959 // Check if the argument is a smi.
1962 Label smi; 1960 Label smi;
1963 STATIC_ASSERT(kSmiTag == 0); 1961 STATIC_ASSERT(kSmiTag == 0);
1964 __ test(eax, Immediate(kSmiTagMask)); 1962 __ test(eax, Immediate(kSmiTagMask));
1965 __ j(zero, &smi); 1963 __ j(zero, &smi);
1966 1964
1967 // Check if the argument is a heap number and load its value into xmm0. 1965 // Check if the argument is a heap number and load its value into xmm0.
1968 Label slow; 1966 Label slow;
1969 __ CheckMap(eax, FACTORY->heap_number_map(), &slow, true); 1967 __ CheckMap(eax, factory()->heap_number_map(), &slow, true);
1970 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 1968 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
1971 1969
1972 // Check if the argument is strictly positive. Note this also 1970 // Check if the argument is strictly positive. Note this also
1973 // discards NaN. 1971 // discards NaN.
1974 __ xorpd(xmm1, xmm1); 1972 __ xorpd(xmm1, xmm1);
1975 __ ucomisd(xmm0, xmm1); 1973 __ ucomisd(xmm0, xmm1);
1976 __ j(below_equal, &slow); 1974 __ j(below_equal, &slow);
1977 1975
1978 // Do a truncating conversion. 1976 // Do a truncating conversion.
1979 __ cvttsd2si(eax, Operand(xmm0)); 1977 __ cvttsd2si(eax, Operand(xmm0));
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 // This only happens for the most negative smi. 2101 // This only happens for the most negative smi.
2104 Label slow; 2102 Label slow;
2105 __ j(negative, &slow); 2103 __ j(negative, &slow);
2106 2104
2107 // Smi case done. 2105 // Smi case done.
2108 __ ret(2 * kPointerSize); 2106 __ ret(2 * kPointerSize);
2109 2107
2110 // Check if the argument is a heap number and load its exponent and 2108 // Check if the argument is a heap number and load its exponent and
2111 // sign into ebx. 2109 // sign into ebx.
2112 __ bind(&not_smi); 2110 __ bind(&not_smi);
2113 __ CheckMap(eax, FACTORY->heap_number_map(), &slow, true); 2111 __ CheckMap(eax, factory()->heap_number_map(), &slow, true);
2114 __ mov(ebx, FieldOperand(eax, HeapNumber::kExponentOffset)); 2112 __ mov(ebx, FieldOperand(eax, HeapNumber::kExponentOffset));
2115 2113
2116 // Check the sign of the argument. If the argument is positive, 2114 // Check the sign of the argument. If the argument is positive,
2117 // just return it. 2115 // just return it.
2118 Label negative_sign; 2116 Label negative_sign;
2119 __ test(ebx, Immediate(HeapNumber::kSignMask)); 2117 __ test(ebx, Immediate(HeapNumber::kSignMask));
2120 __ j(not_zero, &negative_sign); 2118 __ j(not_zero, &negative_sign);
2121 __ ret(2 * kPointerSize); 2119 __ ret(2 * kPointerSize);
2122 2120
2123 // If the argument is negative, clear the sign, and return a new 2121 // If the argument is negative, clear the sign, and return a new
(...skipping 24 matching lines...) Expand all
2148 MaybeObject* CallStubCompiler::CompileFastApiCall( 2146 MaybeObject* CallStubCompiler::CompileFastApiCall(
2149 const CallOptimization& optimization, 2147 const CallOptimization& optimization,
2150 Object* object, 2148 Object* object,
2151 JSObject* holder, 2149 JSObject* holder,
2152 JSGlobalPropertyCell* cell, 2150 JSGlobalPropertyCell* cell,
2153 JSFunction* function, 2151 JSFunction* function,
2154 String* name) { 2152 String* name) {
2155 ASSERT(optimization.is_simple_api_call()); 2153 ASSERT(optimization.is_simple_api_call());
2156 // Bail out if object is a global object as we don't want to 2154 // Bail out if object is a global object as we don't want to
2157 // repatch it to global receiver. 2155 // repatch it to global receiver.
2158 Heap* heap = isolate()->heap(); 2156 if (object->IsGlobalObject()) return heap()->undefined_value();
2159 if (object->IsGlobalObject()) return heap->undefined_value(); 2157 if (cell != NULL) return heap()->undefined_value();
2160 if (cell != NULL) return heap->undefined_value();
2161 int depth = optimization.GetPrototypeDepthOfExpectedType( 2158 int depth = optimization.GetPrototypeDepthOfExpectedType(
2162 JSObject::cast(object), holder); 2159 JSObject::cast(object), holder);
2163 if (depth == kInvalidProtoDepth) return heap->undefined_value(); 2160 if (depth == kInvalidProtoDepth) return heap()->undefined_value();
2164 2161
2165 Label miss, miss_before_stack_reserved; 2162 Label miss, miss_before_stack_reserved;
2166 2163
2167 GenerateNameCheck(name, &miss_before_stack_reserved); 2164 GenerateNameCheck(name, &miss_before_stack_reserved);
2168 2165
2169 // Get the receiver from the stack. 2166 // Get the receiver from the stack.
2170 const int argc = arguments().immediate(); 2167 const int argc = arguments().immediate();
2171 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2168 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2172 2169
2173 // Check that the receiver isn't a smi. 2170 // Check that the receiver isn't a smi.
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2304 } 2301 }
2305 2302
2306 case BOOLEAN_CHECK: { 2303 case BOOLEAN_CHECK: {
2307 if (!function->IsBuiltin() && !function_info->strict_mode()) { 2304 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2308 // Calling non-strict non-builtins with a value as the receiver 2305 // Calling non-strict non-builtins with a value as the receiver
2309 // requires boxing. 2306 // requires boxing.
2310 __ jmp(&miss); 2307 __ jmp(&miss);
2311 } else { 2308 } else {
2312 Label fast; 2309 Label fast;
2313 // Check that the object is a boolean. 2310 // Check that the object is a boolean.
2314 __ cmp(edx, FACTORY->true_value()); 2311 __ cmp(edx, factory()->true_value());
2315 __ j(equal, &fast, taken); 2312 __ j(equal, &fast, taken);
2316 __ cmp(edx, FACTORY->false_value()); 2313 __ cmp(edx, factory()->false_value());
2317 __ j(not_equal, &miss, not_taken); 2314 __ j(not_equal, &miss, not_taken);
2318 __ bind(&fast); 2315 __ bind(&fast);
2319 // Check that the maps starting from the prototype haven't changed. 2316 // Check that the maps starting from the prototype haven't changed.
2320 GenerateDirectLoadGlobalFunctionPrototype( 2317 GenerateDirectLoadGlobalFunctionPrototype(
2321 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); 2318 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss);
2322 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 2319 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
2323 ebx, edx, edi, name, &miss); 2320 ebx, edx, edi, name, &miss);
2324 } 2321 }
2325 break; 2322 break;
2326 } 2323 }
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
2630 Operand cell_operand = Operand::Cell(Handle<JSGlobalPropertyCell>(cell)); 2627 Operand cell_operand = Operand::Cell(Handle<JSGlobalPropertyCell>(cell));
2631 if (Serializer::enabled()) { 2628 if (Serializer::enabled()) {
2632 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); 2629 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell)));
2633 cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset); 2630 cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset);
2634 } 2631 }
2635 2632
2636 // Check that the value in the cell is not the hole. If it is, this 2633 // Check that the value in the cell is not the hole. If it is, this
2637 // cell could have been deleted and reintroducing the global needs 2634 // cell could have been deleted and reintroducing the global needs
2638 // to update the property details in the property dictionary of the 2635 // to update the property details in the property dictionary of the
2639 // global object. We bail out to the runtime system to do that. 2636 // global object. We bail out to the runtime system to do that.
2640 __ cmp(cell_operand, FACTORY->the_hole_value()); 2637 __ cmp(cell_operand, factory()->the_hole_value());
2641 __ j(equal, &miss); 2638 __ j(equal, &miss);
2642 2639
2643 // Store the value in the cell. 2640 // Store the value in the cell.
2644 __ mov(cell_operand, eax); 2641 __ mov(cell_operand, eax);
2645 2642
2646 // Return the value (register eax). 2643 // Return the value (register eax).
2647 Counters* counters = isolate()->counters(); 2644 Counters* counters = isolate()->counters();
2648 __ IncrementCounter(counters->named_store_global_inline(), 1); 2645 __ IncrementCounter(counters->named_store_global_inline(), 1);
2649 __ ret(0); 2646 __ ret(0);
2650 2647
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2716 Immediate(Handle<Map>(receiver->map()))); 2713 Immediate(Handle<Map>(receiver->map())));
2717 __ j(not_equal, &miss, not_taken); 2714 __ j(not_equal, &miss, not_taken);
2718 2715
2719 // Check that the key is a smi. 2716 // Check that the key is a smi.
2720 __ test(ecx, Immediate(kSmiTagMask)); 2717 __ test(ecx, Immediate(kSmiTagMask));
2721 __ j(not_zero, &miss, not_taken); 2718 __ j(not_zero, &miss, not_taken);
2722 2719
2723 // Get the elements array and make sure it is a fast element array, not 'cow'. 2720 // Get the elements array and make sure it is a fast element array, not 'cow'.
2724 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 2721 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
2725 __ cmp(FieldOperand(edi, HeapObject::kMapOffset), 2722 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
2726 Immediate(FACTORY->fixed_array_map())); 2723 Immediate(factory()->fixed_array_map()));
2727 __ j(not_equal, &miss, not_taken); 2724 __ j(not_equal, &miss, not_taken);
2728 2725
2729 // Check that the key is within bounds. 2726 // Check that the key is within bounds.
2730 if (receiver->IsJSArray()) { 2727 if (receiver->IsJSArray()) {
2731 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. 2728 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
2732 __ j(above_equal, &miss, not_taken); 2729 __ j(above_equal, &miss, not_taken);
2733 } else { 2730 } else {
2734 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // Compare smis. 2731 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // Compare smis.
2735 __ j(above_equal, &miss, not_taken); 2732 __ j(above_equal, &miss, not_taken);
2736 } 2733 }
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2928 // Get the value from the cell. 2925 // Get the value from the cell.
2929 if (Serializer::enabled()) { 2926 if (Serializer::enabled()) {
2930 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); 2927 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell)));
2931 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); 2928 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
2932 } else { 2929 } else {
2933 __ mov(ebx, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); 2930 __ mov(ebx, Operand::Cell(Handle<JSGlobalPropertyCell>(cell)));
2934 } 2931 }
2935 2932
2936 // Check for deleted property if property can actually be deleted. 2933 // Check for deleted property if property can actually be deleted.
2937 if (!is_dont_delete) { 2934 if (!is_dont_delete) {
2938 __ cmp(ebx, FACTORY->the_hole_value()); 2935 __ cmp(ebx, factory()->the_hole_value());
2939 __ j(equal, &miss, not_taken); 2936 __ j(equal, &miss, not_taken);
2940 } else if (FLAG_debug_code) { 2937 } else if (FLAG_debug_code) {
2941 __ cmp(ebx, FACTORY->the_hole_value()); 2938 __ cmp(ebx, factory()->the_hole_value());
2942 __ Check(not_equal, "DontDelete cells can't contain the hole"); 2939 __ Check(not_equal, "DontDelete cells can't contain the hole");
2943 } 2940 }
2944 2941
2945 Counters* counters = isolate()->counters(); 2942 Counters* counters = isolate()->counters();
2946 __ IncrementCounter(counters->named_load_global_stub(), 1); 2943 __ IncrementCounter(counters->named_load_global_stub(), 1);
2947 __ mov(eax, ebx); 2944 __ mov(eax, ebx);
2948 __ ret(0); 2945 __ ret(0);
2949 2946
2950 __ bind(&miss); 2947 __ bind(&miss);
2951 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); 2948 __ IncrementCounter(counters->named_load_global_stub_miss(), 1);
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
3188 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 3185 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
3189 __ AssertFastElements(ecx); 3186 __ AssertFastElements(ecx);
3190 3187
3191 // Check that the key is within bounds. 3188 // Check that the key is within bounds.
3192 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset)); 3189 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
3193 __ j(above_equal, &miss, not_taken); 3190 __ j(above_equal, &miss, not_taken);
3194 3191
3195 // Load the result and make sure it's not the hole. 3192 // Load the result and make sure it's not the hole.
3196 __ mov(ebx, Operand(ecx, eax, times_2, 3193 __ mov(ebx, Operand(ecx, eax, times_2,
3197 FixedArray::kHeaderSize - kHeapObjectTag)); 3194 FixedArray::kHeaderSize - kHeapObjectTag));
3198 __ cmp(ebx, FACTORY->the_hole_value()); 3195 __ cmp(ebx, factory()->the_hole_value());
3199 __ j(equal, &miss, not_taken); 3196 __ j(equal, &miss, not_taken);
3200 __ mov(eax, ebx); 3197 __ mov(eax, ebx);
3201 __ ret(0); 3198 __ ret(0);
3202 3199
3203 __ bind(&miss); 3200 __ bind(&miss);
3204 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3201 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3205 3202
3206 // Return the generated code. 3203 // Return the generated code.
3207 return GetCode(NORMAL, NULL); 3204 return GetCode(NORMAL, NULL);
3208 } 3205 }
3209 3206
3210 3207
3211 // Specialized stub for constructing objects from functions which only have only 3208 // Specialized stub for constructing objects from functions which only have only
3212 // simple assignments of the form this.x = ...; in their body. 3209 // simple assignments of the form this.x = ...; in their body.
3213 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3210 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3214 // ----------- S t a t e ------------- 3211 // ----------- S t a t e -------------
3215 // -- eax : argc 3212 // -- eax : argc
3216 // -- edi : constructor 3213 // -- edi : constructor
3217 // -- esp[0] : return address 3214 // -- esp[0] : return address
3218 // -- esp[4] : last argument 3215 // -- esp[4] : last argument
3219 // ----------------------------------- 3216 // -----------------------------------
3220 Label generic_stub_call; 3217 Label generic_stub_call;
3221 #ifdef ENABLE_DEBUGGER_SUPPORT 3218 #ifdef ENABLE_DEBUGGER_SUPPORT
3222 // Check to see whether there are any break points in the function code. If 3219 // Check to see whether there are any break points in the function code. If
3223 // there are jump to the generic constructor stub which calls the actual 3220 // there are jump to the generic constructor stub which calls the actual
3224 // code for the function thereby hitting the break points. 3221 // code for the function thereby hitting the break points.
3225 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 3222 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
3226 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kDebugInfoOffset)); 3223 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kDebugInfoOffset));
3227 __ cmp(ebx, FACTORY->undefined_value()); 3224 __ cmp(ebx, factory()->undefined_value());
3228 __ j(not_equal, &generic_stub_call, not_taken); 3225 __ j(not_equal, &generic_stub_call, not_taken);
3229 #endif 3226 #endif
3230 3227
3231 // Load the initial map and verify that it is in fact a map. 3228 // Load the initial map and verify that it is in fact a map.
3232 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); 3229 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
3233 // Will both indicate a NULL and a Smi. 3230 // Will both indicate a NULL and a Smi.
3234 __ test(ebx, Immediate(kSmiTagMask)); 3231 __ test(ebx, Immediate(kSmiTagMask));
3235 __ j(zero, &generic_stub_call); 3232 __ j(zero, &generic_stub_call);
3236 __ CmpObjectType(ebx, MAP_TYPE, ecx); 3233 __ CmpObjectType(ebx, MAP_TYPE, ecx);
3237 __ j(not_equal, &generic_stub_call); 3234 __ j(not_equal, &generic_stub_call);
(...skipping 16 matching lines...) Expand all
3254 edx, 3251 edx,
3255 ecx, 3252 ecx,
3256 no_reg, 3253 no_reg,
3257 &generic_stub_call, 3254 &generic_stub_call,
3258 NO_ALLOCATION_FLAGS); 3255 NO_ALLOCATION_FLAGS);
3259 3256
3260 // Allocated the JSObject, now initialize the fields and add the heap tag. 3257 // Allocated the JSObject, now initialize the fields and add the heap tag.
3261 // ebx: initial map 3258 // ebx: initial map
3262 // edx: JSObject (untagged) 3259 // edx: JSObject (untagged)
3263 __ mov(Operand(edx, JSObject::kMapOffset), ebx); 3260 __ mov(Operand(edx, JSObject::kMapOffset), ebx);
3264 __ mov(ebx, FACTORY->empty_fixed_array()); 3261 __ mov(ebx, factory()->empty_fixed_array());
3265 __ mov(Operand(edx, JSObject::kPropertiesOffset), ebx); 3262 __ mov(Operand(edx, JSObject::kPropertiesOffset), ebx);
3266 __ mov(Operand(edx, JSObject::kElementsOffset), ebx); 3263 __ mov(Operand(edx, JSObject::kElementsOffset), ebx);
3267 3264
3268 // Push the allocated object to the stack. This is the object that will be 3265 // Push the allocated object to the stack. This is the object that will be
3269 // returned (after it is tagged). 3266 // returned (after it is tagged).
3270 __ push(edx); 3267 __ push(edx);
3271 3268
3272 // eax: argc 3269 // eax: argc
3273 // edx: JSObject (untagged) 3270 // edx: JSObject (untagged)
3274 // Load the address of the first in-object property into edx. 3271 // Load the address of the first in-object property into edx.
3275 __ lea(edx, Operand(edx, JSObject::kHeaderSize)); 3272 __ lea(edx, Operand(edx, JSObject::kHeaderSize));
3276 // Calculate the location of the first argument. The stack contains the 3273 // Calculate the location of the first argument. The stack contains the
3277 // allocated object and the return address on top of the argc arguments. 3274 // allocated object and the return address on top of the argc arguments.
3278 __ lea(ecx, Operand(esp, eax, times_4, 1 * kPointerSize)); 3275 __ lea(ecx, Operand(esp, eax, times_4, 1 * kPointerSize));
3279 3276
3280 // Use edi for holding undefined which is used in several places below. 3277 // Use edi for holding undefined which is used in several places below.
3281 __ mov(edi, FACTORY->undefined_value()); 3278 __ mov(edi, factory()->undefined_value());
3282 3279
3283 // eax: argc 3280 // eax: argc
3284 // ecx: first argument 3281 // ecx: first argument
3285 // edx: first in-object property of the JSObject 3282 // edx: first in-object property of the JSObject
3286 // edi: undefined 3283 // edi: undefined
3287 // Fill the initialized properties with a constant value or a passed argument 3284 // Fill the initialized properties with a constant value or a passed argument
3288 // depending on the this.x = ...; assignment in the function. 3285 // depending on the this.x = ...; assignment in the function.
3289 SharedFunctionInfo* shared = function->shared(); 3286 SharedFunctionInfo* shared = function->shared();
3290 for (int i = 0; i < shared->this_property_assignments_count(); i++) { 3287 for (int i = 0; i < shared->this_property_assignments_count(); i++) {
3291 if (shared->IsThisPropertyAssignmentArgument(i)) { 3288 if (shared->IsThisPropertyAssignmentArgument(i)) {
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
3586 3583
3587 // TODO(danno): handle heap number -> pixel array conversion 3584 // TODO(danno): handle heap number -> pixel array conversion
3588 if (array_type != kExternalPixelArray) { 3585 if (array_type != kExternalPixelArray) {
3589 __ bind(&check_heap_number); 3586 __ bind(&check_heap_number);
3590 // eax: value 3587 // eax: value
3591 // edx: receiver 3588 // edx: receiver
3592 // ecx: key 3589 // ecx: key
3593 // edi: elements array 3590 // edi: elements array
3594 // ebx: untagged index 3591 // ebx: untagged index
3595 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3592 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3596 Immediate(FACTORY->heap_number_map())); 3593 Immediate(factory()->heap_number_map()));
3597 __ j(not_equal, &slow); 3594 __ j(not_equal, &slow);
3598 3595
3599 // The WebGL specification leaves the behavior of storing NaN and 3596 // The WebGL specification leaves the behavior of storing NaN and
3600 // +/-Infinity into integer arrays basically undefined. For more 3597 // +/-Infinity into integer arrays basically undefined. For more
3601 // reproducible behavior, convert these to zero. 3598 // reproducible behavior, convert these to zero.
3602 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3599 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3603 // ebx: untagged index 3600 // ebx: untagged index
3604 // edi: base pointer of external storage 3601 // edi: base pointer of external storage
3605 if (array_type == kExternalFloatArray) { 3602 if (array_type == kExternalFloatArray) {
3606 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3603 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
3704 3701
3705 return GetCode(flags); 3702 return GetCode(flags);
3706 } 3703 }
3707 3704
3708 3705
3709 #undef __ 3706 #undef __
3710 3707
3711 } } // namespace v8::internal 3708 } } // namespace v8::internal
3712 3709
3713 #endif // V8_TARGET_ARCH_IA32 3710 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698