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 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 // Check that the object is a string. | 305 // Check that the object is a string. |
306 __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 306 __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
307 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); | 307 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); |
308 __ and_(scratch2, scratch1, Operand(kIsNotStringMask)); | 308 __ and_(scratch2, scratch1, Operand(kIsNotStringMask)); |
309 // The cast is to resolve the overload for the argument of 0x0. | 309 // The cast is to resolve the overload for the argument of 0x0. |
310 __ cmp(scratch2, Operand(static_cast<int32_t>(kStringTag))); | 310 __ cmp(scratch2, Operand(static_cast<int32_t>(kStringTag))); |
311 __ b(ne, non_string_object); | 311 __ b(ne, non_string_object); |
312 } | 312 } |
313 | 313 |
314 | 314 |
| 315 // Generate code to load the length from a string object and return the length. |
| 316 // If the receiver object is not a string or a wrapped string object the |
| 317 // execution continues at the miss label. The register containing the |
| 318 // receiver is potentially clobbered. |
315 void StubCompiler::GenerateLoadStringLength2(MacroAssembler* masm, | 319 void StubCompiler::GenerateLoadStringLength2(MacroAssembler* masm, |
316 Register receiver, | 320 Register receiver, |
317 Register scratch1, | 321 Register scratch1, |
318 Register scratch2, | 322 Register scratch2, |
319 Label* miss) { | 323 Label* miss) { |
320 Label load_length, check_wrapper; | 324 Label check_string, check_wrapper; |
321 | 325 |
| 326 __ bind(&check_string); |
322 // Check if the object is a string leaving the instance type in the | 327 // Check if the object is a string leaving the instance type in the |
323 // scratch1 register. | 328 // scratch1 register. |
324 GenerateStringCheck(masm, receiver, scratch1, scratch2, | 329 GenerateStringCheck(masm, receiver, scratch1, scratch2, |
325 miss, &check_wrapper); | 330 miss, &check_wrapper); |
326 | 331 |
327 // Load length directly from the string. | 332 // Load length directly from the string. |
328 __ bind(&load_length); | |
329 __ and_(scratch1, scratch1, Operand(kStringSizeMask)); | 333 __ and_(scratch1, scratch1, Operand(kStringSizeMask)); |
330 __ add(scratch1, scratch1, Operand(String::kHashShift)); | 334 __ add(scratch1, scratch1, Operand(String::kHashShift)); |
331 __ ldr(r0, FieldMemOperand(receiver, String::kLengthOffset)); | 335 __ ldr(r0, FieldMemOperand(receiver, String::kLengthOffset)); |
332 __ mov(r0, Operand(r0, LSR, scratch1)); | 336 __ mov(r0, Operand(r0, LSR, scratch1)); |
333 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); | 337 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); |
334 __ Ret(); | 338 __ Ret(); |
335 | 339 |
336 // Check if the object is a JSValue wrapper. | 340 // Check if the object is a JSValue wrapper. |
337 __ bind(&check_wrapper); | 341 __ bind(&check_wrapper); |
338 __ cmp(scratch1, Operand(JS_VALUE_TYPE)); | 342 __ cmp(scratch1, Operand(JS_VALUE_TYPE)); |
339 __ b(ne, miss); | 343 __ b(ne, miss); |
340 | 344 |
341 // Check if the wrapped value is a string and load the length | 345 // Unwrap the value in place and check if the wrapped value is a string. |
342 // directly if it is. | 346 __ ldr(receiver, FieldMemOperand(receiver, JSValue::kValueOffset)); |
343 __ ldr(r0, FieldMemOperand(receiver, JSValue::kValueOffset)); | 347 __ b(&check_string); |
344 GenerateStringCheck(masm, receiver, scratch1, scratch1, miss, miss); | |
345 __ b(&load_length); | |
346 } | 348 } |
347 | 349 |
348 | 350 |
349 // Generate StoreField code, value is passed in r0 register. | 351 // Generate StoreField code, value is passed in r0 register. |
350 // After executing generated code, the receiver_reg and name_reg | 352 // After executing generated code, the receiver_reg and name_reg |
351 // may be clobbered. | 353 // may be clobbered. |
352 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 354 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
353 Builtins::Name storage_extend, | 355 Builtins::Name storage_extend, |
354 JSObject* object, | 356 JSObject* object, |
355 int index, | 357 int index, |
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 __ Jump(ic, RelocInfo::CODE_TARGET); | 1139 __ Jump(ic, RelocInfo::CODE_TARGET); |
1138 | 1140 |
1139 // Return the generated code. | 1141 // Return the generated code. |
1140 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION); | 1142 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION); |
1141 } | 1143 } |
1142 | 1144 |
1143 | 1145 |
1144 #undef __ | 1146 #undef __ |
1145 | 1147 |
1146 } } // namespace v8::internal | 1148 } } // namespace v8::internal |
OLD | NEW |