OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 JSObject::kElementsOffset, | 295 JSObject::kElementsOffset, |
296 r6, | 296 r6, |
297 r9, | 297 r9, |
298 kLRHasBeenSaved, | 298 kLRHasBeenSaved, |
299 kDontSaveFPRegs, | 299 kDontSaveFPRegs, |
300 EMIT_REMEMBERED_SET, | 300 EMIT_REMEMBERED_SET, |
301 OMIT_SMI_CHECK); | 301 OMIT_SMI_CHECK); |
302 __ pop(lr); | 302 __ pop(lr); |
303 } | 303 } |
304 | 304 |
305 | |
306 void StringCharLoadGenerator::Generate(MacroAssembler* masm, | |
307 Register string, | |
308 Register index, | |
309 Register result, | |
310 Label* call_runtime) { | |
311 // Fetch the instance type of the receiver into result register. | |
312 __ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset)); | |
313 __ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); | |
314 | |
315 // We need special handling for indirect strings. | |
316 Label check_sequential; | |
317 __ tst(result, Operand(kIsIndirectStringMask)); | |
318 __ b(eq, &check_sequential); | |
319 | |
320 // Dispatch on the indirect string shape: slice or cons. | |
321 Label cons_string; | |
322 __ tst(result, Operand(kSlicedNotConsMask)); | |
323 __ b(eq, &cons_string); | |
324 | |
325 // Handle slices. | |
326 Label indirect_string_loaded; | |
327 __ ldr(result, FieldMemOperand(string, SlicedString::kOffsetOffset)); | |
328 __ add(index, index, Operand(result, ASR, kSmiTagSize)); | |
329 __ ldr(string, FieldMemOperand(string, SlicedString::kParentOffset)); | |
330 __ jmp(&indirect_string_loaded); | |
331 | |
332 // Handle external strings. | |
Rico
2011/11/24 06:55:15
Any reason for not just having this be fall-throug
Yang
2011/11/24 11:15:11
Done.
| |
333 Label external_string, ascii_external, done; | |
334 __ bind(&external_string); | |
335 if (FLAG_debug_code) { | |
336 // Assert that we do not have a cons or slice (indirect strings) here. | |
337 // Sequential strings have already been ruled out. | |
338 __ tst(result, Operand(kIsIndirectStringMask)); | |
339 __ Assert(eq, "external string expected, but not found"); | |
340 } | |
341 // Rule out short external strings. | |
342 STATIC_CHECK(kShortExternalStringTag != 0); | |
343 __ tst(result, Operand(kShortExternalStringMask)); | |
344 __ b(ne, call_runtime); | |
345 // Check encoding. | |
346 STATIC_ASSERT(kTwoByteStringTag == 0); | |
347 __ tst(result, Operand(kStringEncodingMask)); | |
348 __ ldr(result, FieldMemOperand(string, ExternalString::kResourceDataOffset)); | |
349 __ b(ne, &ascii_external); | |
350 // Two-byte string. | |
351 __ ldrh(result, MemOperand(result, index, LSL, 1)); | |
352 __ jmp(&done); | |
353 __ bind(&ascii_external); | |
354 // Ascii string. | |
355 __ ldrb(result, MemOperand(result, index)); | |
356 __ jmp(&done); | |
357 | |
358 // Handle conses. | |
Rico
2011/11/24 06:55:15
Handle cons strings?
Yang
2011/11/24 11:15:11
Done.
| |
359 // Check whether the right hand side is the empty string (i.e. if | |
360 // this is really a flat string in a cons string). If that is not | |
361 // the case we would rather go to the runtime system now to flatten | |
362 // the string. | |
363 __ bind(&cons_string); | |
364 __ ldr(result, FieldMemOperand(string, ConsString::kSecondOffset)); | |
365 __ LoadRoot(ip, Heap::kEmptyStringRootIndex); | |
366 __ cmp(result, ip); | |
367 __ b(ne, call_runtime); | |
368 // Get the first of the two strings and load its instance type. | |
369 __ ldr(string, FieldMemOperand(string, ConsString::kFirstOffset)); | |
370 | |
371 __ bind(&indirect_string_loaded); | |
372 __ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset)); | |
373 __ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); | |
374 | |
375 // Check whether the string is sequential. The only non-sequential | |
376 // shapes we support have just been unwrapped above. | |
377 // Note that if the original string is a cons or slice with an external | |
378 // string as underlying string, we pass that unpacked underlying string with | |
379 // the adjusted index to the runtime function. | |
Rico
2011/11/24 06:55:15
Please fix comment, we don't do this anymore. Plea
Yang
2011/11/24 11:15:11
Done.
| |
380 __ bind(&check_sequential); | |
381 STATIC_ASSERT(kSeqStringTag == 0); | |
382 __ tst(result, Operand(kStringRepresentationMask)); | |
383 __ b(ne, &external_string); | |
384 | |
385 // Dispatch on the encoding: ASCII or two-byte. | |
386 Label ascii_string; | |
387 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); | |
388 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); | |
389 __ tst(result, Operand(kStringEncodingMask)); | |
390 __ b(ne, &ascii_string); | |
391 | |
392 // Two-byte string. | |
393 // Load the two-byte character code into the result register. | |
394 __ add(result, | |
395 string, | |
396 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | |
397 __ ldrh(result, MemOperand(result, index, LSL, 1)); | |
398 __ jmp(&done); | |
399 | |
400 // ASCII string. | |
401 // Load the byte into the result register. | |
402 __ bind(&ascii_string); | |
403 __ add(result, | |
404 string, | |
405 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | |
406 __ ldrb(result, MemOperand(result, index)); | |
407 | |
408 __ bind(&done); | |
409 } | |
410 | |
305 #undef __ | 411 #undef __ |
306 | 412 |
307 } } // namespace v8::internal | 413 } } // namespace v8::internal |
308 | 414 |
309 #endif // V8_TARGET_ARCH_ARM | 415 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |