868
868
// -- lr : return address
869
869
// -----------------------------------
870
870
Label slow, notin;
871
// Store address is returned in register (of MemOperand) mapped_location.
871
872
MemOperand mapped_location =
872
873
GenerateMappedArgumentsLookup(masm, a2, a1, a3, t0, t1, ¬in, &slow);
873
874
__ sw(a0, mapped_location);
876
__ RecordWrite(a3, t2, t5, kRAHasNotBeenSaved, kDontSaveFPRegs);
876
ASSERT_EQ(mapped_location.offset(), 0);
877
__ RecordWrite(a3, mapped_location.rm(), t5,
878
kRAHasNotBeenSaved, kDontSaveFPRegs);
877
879
__ Ret(USE_DELAY_SLOT);
878
880
__ mov(v0, a0); // (In delay slot) return the value stored in v0.
880
882
// The unmapped lookup expects that the parameter map is in a3.
883
// Store address is returned in register (of MemOperand) unmapped_location.
881
884
MemOperand unmapped_location =
882
885
GenerateUnmappedArgumentsLookup(masm, a1, a3, t0, &slow);
883
886
__ sw(a0, unmapped_location);
886
__ RecordWrite(a3, t2, t5, kRAHasNotBeenSaved, kDontSaveFPRegs);
888
ASSERT_EQ(unmapped_location.offset(), 0);
889
__ RecordWrite(a3, unmapped_location.rm(), t5,
890
kRAHasNotBeenSaved, kDontSaveFPRegs);
887
891
__ Ret(USE_DELAY_SLOT);
888
892
__ mov(v0, a0); // (In delay slot) return the value stored in v0.
1029
1033
__ lw(t0, FieldMemOperand(a0, String::kHashFieldOffset));
1030
1034
__ sra(at, t0, String::kHashShift);
1031
1035
__ xor_(a3, a3, at);
1032
__ And(a3, a3, Operand(KeyedLookupCache::kCapacityMask));
1036
int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask;
1037
__ And(a3, a3, Operand(mask));
1034
1039
// Load the key (consisting of map and symbol) from the cache and
1035
1040
// check for match.
1041
Label load_in_object_property;
1042
static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket;
1043
Label hit_on_nth_entry[kEntriesPerBucket];
1036
1044
ExternalReference cache_keys =
1037
1045
ExternalReference::keyed_lookup_cache_keys(isolate);
1038
1046
__ li(t0, Operand(cache_keys));
1039
1047
__ sll(at, a3, kPointerSizeLog2 + 1);
1040
1048
__ addu(t0, t0, at);
1041
__ lw(t1, MemOperand(t0)); // Move t0 to symbol.
1042
__ Addu(t0, t0, Operand(kPointerSize));
1050
for (int i = 0; i < kEntriesPerBucket - 1; i++) {
1051
Label try_next_entry;
1052
__ lw(t1, MemOperand(t0, kPointerSize * i * 2));
1053
__ Branch(&try_next_entry, ne, a2, Operand(t1));
1054
__ lw(t1, MemOperand(t0, kPointerSize * (i * 2 + 1)));
1055
__ Branch(&hit_on_nth_entry[i], eq, a0, Operand(t1));
1056
__ bind(&try_next_entry);
1059
__ lw(t1, MemOperand(t0, kPointerSize * (kEntriesPerBucket - 1) * 2));
1043
1060
__ Branch(&slow, ne, a2, Operand(t1));
1044
__ lw(t1, MemOperand(t0));
1061
__ lw(t1, MemOperand(t0, kPointerSize * ((kEntriesPerBucket - 1) * 2 + 1)));
1045
1062
__ Branch(&slow, ne, a0, Operand(t1));
1047
1064
// Get field offset.
1051
1068
// a3 : lookup cache index
1052
1069
ExternalReference cache_field_offsets =
1053
1070
ExternalReference::keyed_lookup_cache_field_offsets(isolate);
1054
__ li(t0, Operand(cache_field_offsets));
1055
__ sll(at, a3, kPointerSizeLog2);
1056
__ addu(at, t0, at);
1057
__ lw(t1, MemOperand(at));
1058
__ lbu(t2, FieldMemOperand(a2, Map::kInObjectPropertiesOffset));
1059
__ Subu(t1, t1, t2);
1060
__ Branch(&property_array_property, ge, t1, Operand(zero_reg));
1072
// Hit on nth entry.
1073
for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
1074
__ bind(&hit_on_nth_entry[i]);
1075
__ li(t0, Operand(cache_field_offsets));
1076
__ sll(at, a3, kPointerSizeLog2);
1077
__ addu(at, t0, at);
1078
__ lw(t1, MemOperand(at, kPointerSize * i));
1079
__ lbu(t2, FieldMemOperand(a2, Map::kInObjectPropertiesOffset));
1080
__ Subu(t1, t1, t2);
1081
__ Branch(&property_array_property, ge, t1, Operand(zero_reg));
1083
__ Branch(&load_in_object_property);
1062
1087
// Load in-object property.
1088
__ bind(&load_in_object_property);
1063
1089
__ lbu(t2, FieldMemOperand(a2, Map::kInstanceSizeOffset));
1064
1090
__ addu(t2, t2, t1); // Index from start of object.
1065
1091
__ Subu(a1, a1, Operand(kHeapObjectTag)); // Remove the heap tag.
1470
1496
// -- ra : return address
1471
1497
// -----------------------------------
1473
// This accepts as a receiver anything JSObject::SetElementsLength accepts
1474
// (currently anything except for external and pixel arrays which means
1475
// anything with elements of FixedArray type.), but currently is restricted
1477
// Value must be a number, but only smis are accepted as the most common case.
1499
// This accepts as a receiver anything JSArray::SetElementsLength accepts
1500
// (currently anything except for external arrays which means anything with
1501
// elements of FixedArray type). Value must be a number, but only smis are
1502
// accepted as the most common case.
1496
1521
__ GetObjectType(scratch, scratch, scratch);
1497
1522
__ Branch(&miss, ne, scratch, Operand(FIXED_ARRAY_TYPE));
1524
// Check that the array has fast properties, otherwise the length
1525
// property might have been redefined.
1526
// TODO(mstarzinger): Port this check to MIPS.
1499
1528
// Check that value is a smi.
1500
1529
__ JumpIfNotSmi(value, &miss);
1587
1616
rewritten = stub.GetCode();
1589
1618
ICCompareStub stub(op_, state);
1619
if (state == KNOWN_OBJECTS) {
1620
stub.set_known_map(Handle<Map>(Handle<JSObject>::cast(x)->map()));
1590
1622
rewritten = stub.GetCode();
1592
1624
set_target(*rewritten);