OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 152 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
153 __ cmp(scratch, JS_ARRAY_TYPE); | 153 __ cmp(scratch, JS_ARRAY_TYPE); |
154 __ j(not_equal, miss_label, not_taken); | 154 __ j(not_equal, miss_label, not_taken); |
155 | 155 |
156 // Load length directly from the JS array. | 156 // Load length directly from the JS array. |
157 __ mov(eax, FieldOperand(receiver, JSArray::kLengthOffset)); | 157 __ mov(eax, FieldOperand(receiver, JSArray::kLengthOffset)); |
158 __ ret(0); | 158 __ ret(0); |
159 } | 159 } |
160 | 160 |
161 | 161 |
| 162 // Generate code to check is an object is a string. If the object is |
| 163 // a string, the map's instance type is left in the scratch register. |
| 164 static void GenerateStringCheck(MacroAssembler* masm, |
| 165 Register receiver, |
| 166 Register scratch, |
| 167 Label* smi, |
| 168 Label* non_string_object) { |
| 169 // Check that the object isn't a smi. |
| 170 __ test(receiver, Immediate(kSmiTagMask)); |
| 171 __ j(zero, smi, not_taken); |
| 172 |
| 173 // Check that the object is a string. |
| 174 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 175 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 176 ASSERT(kNotStringTag != 0); |
| 177 __ test(scratch, Immediate(kNotStringTag)); |
| 178 __ j(not_zero, non_string_object, not_taken); |
| 179 } |
| 180 |
| 181 |
162 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, | 182 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, |
163 Register receiver, | 183 Register receiver, |
164 Register scratch, | 184 Register scratch, |
165 Label* miss_label) { | 185 Label* miss) { |
166 // Check that the receiver isn't a smi. | 186 Label load_length, check_wrapper; |
167 __ test(receiver, Immediate(kSmiTagMask)); | |
168 __ j(zero, miss_label, not_taken); | |
169 | 187 |
170 // Check that the object is a string. | 188 // Check if the object is a string. |
171 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 189 GenerateStringCheck(masm, receiver, scratch, miss, &check_wrapper); |
172 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | |
173 ASSERT(kNotStringTag != 0); | |
174 __ test(scratch, Immediate(kNotStringTag)); | |
175 __ j(not_zero, miss_label, not_taken); | |
176 | |
177 __ and_(scratch, kStringSizeMask); | |
178 | 190 |
179 // Load length directly from the string. | 191 // Load length directly from the string. |
| 192 __ bind(&load_length); |
| 193 __ and_(scratch, kStringSizeMask); |
180 __ mov(eax, FieldOperand(receiver, String::kLengthOffset)); | 194 __ mov(eax, FieldOperand(receiver, String::kLengthOffset)); |
181 | |
182 // ecx is also the receiver. | 195 // ecx is also the receiver. |
183 __ lea(ecx, Operand(scratch, String::kLongLengthShift)); | 196 __ lea(ecx, Operand(scratch, String::kLongLengthShift)); |
184 __ shr(eax); // ecx is implicit shift register. | 197 __ shr(eax); // ecx is implicit shift register. |
185 __ shl(eax, kSmiTagSize); | 198 __ shl(eax, kSmiTagSize); |
186 __ ret(0); | 199 __ ret(0); |
| 200 |
| 201 // Check if the object is a JSValue wrapper. |
| 202 __ bind(&check_wrapper); |
| 203 __ cmp(receiver, JS_VALUE_TYPE); |
| 204 __ j(not_equal, miss, not_taken); |
| 205 |
| 206 // Check if the wrapped value is a string and load the length |
| 207 // directly if it is. |
| 208 __ mov(receiver, FieldOperand(receiver, JSValue::kValueOffset)); |
| 209 GenerateStringCheck(masm, receiver, scratch, miss, miss); |
| 210 __ jmp(&load_length); |
187 } | 211 } |
188 | 212 |
189 | 213 |
190 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, | 214 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, |
191 Register receiver, | 215 Register receiver, |
192 Register scratch1, | 216 Register scratch1, |
193 Register scratch2, | 217 Register scratch2, |
194 Label* miss_label) { | 218 Label* miss_label) { |
195 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); | 219 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); |
196 __ mov(eax, Operand(scratch1)); | 220 __ mov(eax, Operand(scratch1)); |
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1187 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1164 | 1188 |
1165 // Return the generated code. | 1189 // Return the generated code. |
1166 return GetCode(CALLBACKS); | 1190 return GetCode(CALLBACKS); |
1167 } | 1191 } |
1168 | 1192 |
1169 | 1193 |
1170 #undef __ | 1194 #undef __ |
1171 | 1195 |
1172 } } // namespace v8::internal | 1196 } } // namespace v8::internal |
OLD | NEW |