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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 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/code-stubs-ia32.h ('k') | src/ia32/codegen-ia32.cc » ('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 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 2398 matching lines...) Expand 10 before | Expand all | Expand 10 after
2409 case Token::SHR: 2409 case Token::SHR:
2410 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); 2410 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION);
2411 break; 2411 break;
2412 default: 2412 default:
2413 UNREACHABLE(); 2413 UNREACHABLE();
2414 } 2414 }
2415 } 2415 }
2416 2416
2417 2417
2418 void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { 2418 void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
2419 NearLabel call_runtime; 2419 ASSERT(op_ == Token::ADD);
2420 NearLabel left_not_string, call_runtime;
2420 2421
2421 // Registers containing left and right operands respectively. 2422 // Registers containing left and right operands respectively.
2422 Register left = edx; 2423 Register left = edx;
2423 Register right = eax; 2424 Register right = eax;
2424 2425
2425 // Test if left operand is a string. 2426 // Test if left operand is a string.
2426 NearLabel left_not_string;
2427 __ test(left, Immediate(kSmiTagMask)); 2427 __ test(left, Immediate(kSmiTagMask));
2428 __ j(zero, &left_not_string); 2428 __ j(zero, &left_not_string);
2429 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); 2429 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx);
2430 __ j(above_equal, &left_not_string); 2430 __ j(above_equal, &left_not_string);
2431 2431
2432 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); 2432 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB);
2433 GenerateRegisterArgsPush(masm); 2433 GenerateRegisterArgsPush(masm);
2434 __ TailCallStub(&string_add_left_stub); 2434 __ TailCallStub(&string_add_left_stub);
2435 2435
2436 // Left operand is not a string, test right. 2436 // Left operand is not a string, test right.
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after
3423 __ cvtsi2sd(xmm3, Operand(ecx)); 3423 __ cvtsi2sd(xmm3, Operand(ecx));
3424 3424
3425 Label exponent_nonsmi; 3425 Label exponent_nonsmi;
3426 Label base_nonsmi; 3426 Label base_nonsmi;
3427 // If the exponent is a heap number go to that specific case. 3427 // If the exponent is a heap number go to that specific case.
3428 __ test(eax, Immediate(kSmiTagMask)); 3428 __ test(eax, Immediate(kSmiTagMask));
3429 __ j(not_zero, &exponent_nonsmi); 3429 __ j(not_zero, &exponent_nonsmi);
3430 __ test(edx, Immediate(kSmiTagMask)); 3430 __ test(edx, Immediate(kSmiTagMask));
3431 __ j(not_zero, &base_nonsmi); 3431 __ j(not_zero, &base_nonsmi);
3432 3432
3433 // Optimized version when both exponent and base is a smi. 3433 // Optimized version when both exponent and base are smis.
3434 Label powi; 3434 Label powi;
3435 __ SmiUntag(edx); 3435 __ SmiUntag(edx);
3436 __ cvtsi2sd(xmm0, Operand(edx)); 3436 __ cvtsi2sd(xmm0, Operand(edx));
3437 __ jmp(&powi); 3437 __ jmp(&powi);
3438 // exponent is smi and base is a heapnumber. 3438 // exponent is smi and base is a heapnumber.
3439 __ bind(&base_nonsmi); 3439 __ bind(&base_nonsmi);
3440 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 3440 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
3441 Factory::heap_number_map()); 3441 Factory::heap_number_map());
3442 __ j(not_equal, &call_runtime); 3442 __ j(not_equal, &call_runtime);
3443 3443
(...skipping 18 matching lines...) Expand all
3462 // Load xmm1 with 1. 3462 // Load xmm1 with 1.
3463 __ movsd(xmm1, xmm3); 3463 __ movsd(xmm1, xmm3);
3464 NearLabel while_true; 3464 NearLabel while_true;
3465 NearLabel no_multiply; 3465 NearLabel no_multiply;
3466 3466
3467 __ bind(&while_true); 3467 __ bind(&while_true);
3468 __ shr(eax, 1); 3468 __ shr(eax, 1);
3469 __ j(not_carry, &no_multiply); 3469 __ j(not_carry, &no_multiply);
3470 __ mulsd(xmm1, xmm0); 3470 __ mulsd(xmm1, xmm0);
3471 __ bind(&no_multiply); 3471 __ bind(&no_multiply);
3472 __ test(eax, Operand(eax));
3473 __ mulsd(xmm0, xmm0); 3472 __ mulsd(xmm0, xmm0);
3474 __ j(not_zero, &while_true); 3473 __ j(not_zero, &while_true);
3475 3474
3476 // base has the original value of the exponent - if the exponent is 3475 // base has the original value of the exponent - if the exponent is
3477 // negative return 1/result. 3476 // negative return 1/result.
3478 __ test(edx, Operand(edx)); 3477 __ test(edx, Operand(edx));
3479 __ j(positive, &allocate_return); 3478 __ j(positive, &allocate_return);
3480 // Special case if xmm1 has reached infinity. 3479 // Special case if xmm1 has reached infinity.
3481 __ mov(ecx, Immediate(0x7FB00000)); 3480 __ mov(ecx, Immediate(0x7FB00000));
3482 __ movd(xmm0, Operand(ecx)); 3481 __ movd(xmm0, Operand(ecx));
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3549 // Calculates square root. 3548 // Calculates square root.
3550 // sqrtsd returns -0 when input is -0. ECMA spec requires +0. 3549 // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
3551 __ xorpd(xmm1, xmm1); 3550 __ xorpd(xmm1, xmm1);
3552 __ addsd(xmm1, xmm0); 3551 __ addsd(xmm1, xmm0);
3553 __ sqrtsd(xmm1, xmm1); 3552 __ sqrtsd(xmm1, xmm1);
3554 3553
3555 __ bind(&allocate_return); 3554 __ bind(&allocate_return);
3556 __ AllocateHeapNumber(ecx, eax, edx, &call_runtime); 3555 __ AllocateHeapNumber(ecx, eax, edx, &call_runtime);
3557 __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm1); 3556 __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm1);
3558 __ mov(eax, ecx); 3557 __ mov(eax, ecx);
3559 __ ret(2); 3558 __ ret(2 * kPointerSize);
3560 3559
3561 __ bind(&call_runtime); 3560 __ bind(&call_runtime);
3562 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1); 3561 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
3563 } 3562 }
3564 3563
3565 3564
3566 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { 3565 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
3567 // The key is in edx and the parameter count is in eax. 3566 // The key is in edx and the parameter count is in eax.
3568 3567
3569 // The displacement is used for skipping the frame pointer on the 3568 // The displacement is used for skipping the frame pointer on the
(...skipping 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after
4676 // of the original receiver from the call site). 4675 // of the original receiver from the call site).
4677 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); 4676 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi);
4678 __ Set(eax, Immediate(argc_)); 4677 __ Set(eax, Immediate(argc_));
4679 __ Set(ebx, Immediate(0)); 4678 __ Set(ebx, Immediate(0));
4680 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); 4679 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
4681 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); 4680 Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
4682 __ jmp(adaptor, RelocInfo::CODE_TARGET); 4681 __ jmp(adaptor, RelocInfo::CODE_TARGET);
4683 } 4682 }
4684 4683
4685 4684
4685 bool CEntryStub::NeedsImmovableCode() {
4686 return false;
4687 }
4688
4689
4686 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { 4690 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
4687 __ Throw(eax); 4691 __ Throw(eax);
4688 } 4692 }
4689 4693
4690 4694
4691 void CEntryStub::GenerateCore(MacroAssembler* masm, 4695 void CEntryStub::GenerateCore(MacroAssembler* masm,
4692 Label* throw_normal_exception, 4696 Label* throw_normal_exception,
4693 Label* throw_termination_exception, 4697 Label* throw_termination_exception,
4694 Label* throw_out_of_memory_exception, 4698 Label* throw_out_of_memory_exception,
4695 bool do_gc, 4699 bool do_gc,
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after
5533 // ebx: length of first string as a smi 5537 // ebx: length of first string as a smi
5534 // ecx: length of second string as a smi 5538 // ecx: length of second string as a smi
5535 // edx: second string 5539 // edx: second string
5536 // Look at the length of the result of adding the two strings. 5540 // Look at the length of the result of adding the two strings.
5537 Label string_add_flat_result, longer_than_two; 5541 Label string_add_flat_result, longer_than_two;
5538 __ bind(&both_not_zero_length); 5542 __ bind(&both_not_zero_length);
5539 __ add(ebx, Operand(ecx)); 5543 __ add(ebx, Operand(ecx));
5540 STATIC_ASSERT(Smi::kMaxValue == String::kMaxLength); 5544 STATIC_ASSERT(Smi::kMaxValue == String::kMaxLength);
5541 // Handle exceptionally long strings in the runtime system. 5545 // Handle exceptionally long strings in the runtime system.
5542 __ j(overflow, &string_add_runtime); 5546 __ j(overflow, &string_add_runtime);
5543 // Use the runtime system when adding two one character strings, as it 5547 // Use the symbol table when adding two one character strings, as it
5544 // contains optimizations for this specific case using the symbol table. 5548 // helps later optimizations to return a symbol here.
5545 __ cmp(Operand(ebx), Immediate(Smi::FromInt(2))); 5549 __ cmp(Operand(ebx), Immediate(Smi::FromInt(2)));
5546 __ j(not_equal, &longer_than_two); 5550 __ j(not_equal, &longer_than_two);
5547 5551
5548 // Check that both strings are non-external ascii strings. 5552 // Check that both strings are non-external ascii strings.
5549 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx, 5553 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx,
5550 &string_add_runtime); 5554 &string_add_runtime);
5551 5555
5552 // Get the two characters forming the new string. 5556 // Get the two characters forming the new string.
5553 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize)); 5557 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
5554 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize)); 5558 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
5951 STATIC_ASSERT(SymbolTable::kEntrySize == 1); 5955 STATIC_ASSERT(SymbolTable::kEntrySize == 1);
5952 __ mov(candidate, 5956 __ mov(candidate,
5953 FieldOperand(symbol_table, 5957 FieldOperand(symbol_table,
5954 scratch, 5958 scratch,
5955 times_pointer_size, 5959 times_pointer_size,
5956 SymbolTable::kElementsStartOffset)); 5960 SymbolTable::kElementsStartOffset));
5957 5961
5958 // If entry is undefined no string with this hash can be found. 5962 // If entry is undefined no string with this hash can be found.
5959 __ cmp(candidate, Factory::undefined_value()); 5963 __ cmp(candidate, Factory::undefined_value());
5960 __ j(equal, not_found); 5964 __ j(equal, not_found);
5965 __ cmp(candidate, Factory::null_value());
5966 __ j(equal, &next_probe[i]);
5961 5967
5962 // If length is not 2 the string is not a candidate. 5968 // If length is not 2 the string is not a candidate.
5963 __ cmp(FieldOperand(candidate, String::kLengthOffset), 5969 __ cmp(FieldOperand(candidate, String::kLengthOffset),
5964 Immediate(Smi::FromInt(2))); 5970 Immediate(Smi::FromInt(2)));
5965 __ j(not_equal, &next_probe[i]); 5971 __ j(not_equal, &next_probe[i]);
5966 5972
5967 // As we are out of registers save the mask on the stack and use that 5973 // As we are out of registers save the mask on the stack and use that
5968 // register as a temporary. 5974 // register as a temporary.
5969 __ push(mask); 5975 __ push(mask);
5970 Register temp = mask; 5976 Register temp = mask;
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
6319 __ push(ecx); 6325 __ push(ecx);
6320 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); 6326 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi);
6321 6327
6322 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 6328 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
6323 // tagged as a small integer. 6329 // tagged as a small integer.
6324 __ bind(&runtime); 6330 __ bind(&runtime);
6325 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 6331 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
6326 } 6332 }
6327 6333
6328 6334
6329 void StringCharAtStub::Generate(MacroAssembler* masm) {
6330 // Expects two arguments (object, index) on the stack:
6331
6332 // Stack frame on entry.
6333 // esp[0]: return address
6334 // esp[4]: index
6335 // esp[8]: object
6336
6337 Register object = ebx;
6338 Register index = eax;
6339 Register scratch1 = ecx;
6340 Register scratch2 = edx;
6341 Register result = eax;
6342
6343 __ pop(scratch1); // Return address.
6344 __ pop(index);
6345 __ pop(object);
6346 __ push(scratch1);
6347
6348 Label need_conversion;
6349 Label index_out_of_range;
6350 Label done;
6351 StringCharAtGenerator generator(object,
6352 index,
6353 scratch1,
6354 scratch2,
6355 result,
6356 &need_conversion,
6357 &need_conversion,
6358 &index_out_of_range,
6359 STRING_INDEX_IS_NUMBER);
6360 generator.GenerateFast(masm);
6361 __ jmp(&done);
6362
6363 __ bind(&index_out_of_range);
6364 // When the index is out of range, the spec requires us to return
6365 // the empty string.
6366 __ Set(result, Immediate(Factory::empty_string()));
6367 __ jmp(&done);
6368
6369 __ bind(&need_conversion);
6370 // Move smi zero into the result register, which will trigger
6371 // conversion.
6372 __ Set(result, Immediate(Smi::FromInt(0)));
6373 __ jmp(&done);
6374
6375 StubRuntimeCallHelper call_helper;
6376 generator.GenerateSlow(masm, call_helper);
6377
6378 __ bind(&done);
6379 __ ret(0);
6380 }
6381
6382 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { 6335 void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
6383 ASSERT(state_ == CompareIC::SMIS); 6336 ASSERT(state_ == CompareIC::SMIS);
6384 NearLabel miss; 6337 NearLabel miss;
6385 __ mov(ecx, Operand(edx)); 6338 __ mov(ecx, Operand(edx));
6386 __ or_(ecx, Operand(eax)); 6339 __ or_(ecx, Operand(eax));
6387 __ test(ecx, Immediate(kSmiTagMask)); 6340 __ test(ecx, Immediate(kSmiTagMask));
6388 __ j(not_zero, &miss, not_taken); 6341 __ j(not_zero, &miss, not_taken);
6389 6342
6390 if (GetCondition() == equal) { 6343 if (GetCondition() == equal) {
6391 // For equality we do not care about the sign of the result. 6344 // For equality we do not care about the sign of the result.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
6504 __ pop(ecx); 6457 __ pop(ecx);
6505 __ pop(eax); 6458 __ pop(eax);
6506 __ pop(edx); 6459 __ pop(edx);
6507 __ push(ecx); 6460 __ push(ecx);
6508 6461
6509 // Do a tail call to the rewritten stub. 6462 // Do a tail call to the rewritten stub.
6510 __ jmp(Operand(edi)); 6463 __ jmp(Operand(edi));
6511 } 6464 }
6512 6465
6513 6466
6514 // Loads a indexed element from a pixel array.
6515 void GenerateFastPixelArrayLoad(MacroAssembler* masm,
6516 Register receiver,
6517 Register key,
6518 Register elements,
6519 Register untagged_key,
6520 Register result,
6521 Label* not_pixel_array,
6522 Label* key_not_smi,
6523 Label* out_of_range) {
6524 // Register use:
6525 // receiver - holds the receiver and is unchanged.
6526 // key - holds the key and is unchanged (must be a smi).
6527 // elements - is set to the the receiver's element if
6528 // the receiver doesn't have a pixel array or the
6529 // key is not a smi, otherwise it's the elements'
6530 // external pointer.
6531 // untagged_key - is set to the untagged key
6532
6533 // Some callers already have verified that the key is a smi. key_not_smi is
6534 // set to NULL as a sentinel for that case. Otherwise, add an explicit check
6535 // to ensure the key is a smi must be added.
6536 if (key_not_smi != NULL) {
6537 __ JumpIfNotSmi(key, key_not_smi);
6538 } else {
6539 if (FLAG_debug_code) {
6540 __ AbortIfNotSmi(key);
6541 }
6542 }
6543 __ mov(untagged_key, key);
6544 __ SmiUntag(untagged_key);
6545
6546 __ mov(elements, FieldOperand(receiver, JSObject::kElementsOffset));
6547 // By passing NULL as not_pixel_array, callers signal that they have already
6548 // verified that the receiver has pixel array elements.
6549 if (not_pixel_array != NULL) {
6550 __ CheckMap(elements, Factory::pixel_array_map(), not_pixel_array, true);
6551 } else {
6552 if (FLAG_debug_code) {
6553 // Map check should have already made sure that elements is a pixel array.
6554 __ cmp(FieldOperand(elements, HeapObject::kMapOffset),
6555 Immediate(Factory::pixel_array_map()));
6556 __ Assert(equal, "Elements isn't a pixel array");
6557 }
6558 }
6559
6560 // Key must be in range.
6561 __ cmp(untagged_key, FieldOperand(elements, PixelArray::kLengthOffset));
6562 __ j(above_equal, out_of_range); // unsigned check handles negative keys.
6563
6564 // Perform the indexed load and tag the result as a smi.
6565 __ mov(elements, FieldOperand(elements, PixelArray::kExternalPointerOffset));
6566 __ movzx_b(result, Operand(elements, untagged_key, times_1, 0));
6567 __ SmiTag(result);
6568 __ ret(0);
6569 }
6570
6571
6572 // Stores an indexed element into a pixel array, clamping the stored value.
6573 void GenerateFastPixelArrayStore(MacroAssembler* masm,
6574 Register receiver,
6575 Register key,
6576 Register value,
6577 Register elements,
6578 Register scratch1,
6579 bool load_elements_from_receiver,
6580 Label* key_not_smi,
6581 Label* value_not_smi,
6582 Label* not_pixel_array,
6583 Label* out_of_range) {
6584 // Register use:
6585 // receiver - holds the receiver and is unchanged unless the
6586 // store succeeds.
6587 // key - holds the key (must be a smi) and is unchanged.
6588 // value - holds the value (must be a smi) and is unchanged.
6589 // elements - holds the element object of the receiver on entry if
6590 // load_elements_from_receiver is false, otherwise used
6591 // internally to store the pixel arrays elements and
6592 // external array pointer.
6593 //
6594 // receiver, key and value remain unmodified until it's guaranteed that the
6595 // store will succeed.
6596 Register external_pointer = elements;
6597 Register untagged_key = scratch1;
6598 Register untagged_value = receiver; // Only set once success guaranteed.
6599
6600 // Fetch the receiver's elements if the caller hasn't already done so.
6601 if (load_elements_from_receiver) {
6602 __ mov(elements, FieldOperand(receiver, JSObject::kElementsOffset));
6603 }
6604
6605 // By passing NULL as not_pixel_array, callers signal that they have already
6606 // verified that the receiver has pixel array elements.
6607 if (not_pixel_array != NULL) {
6608 __ CheckMap(elements, Factory::pixel_array_map(), not_pixel_array, true);
6609 } else {
6610 if (FLAG_debug_code) {
6611 // Map check should have already made sure that elements is a pixel array.
6612 __ cmp(FieldOperand(elements, HeapObject::kMapOffset),
6613 Immediate(Factory::pixel_array_map()));
6614 __ Assert(equal, "Elements isn't a pixel array");
6615 }
6616 }
6617
6618 // Some callers already have verified that the key is a smi. key_not_smi is
6619 // set to NULL as a sentinel for that case. Otherwise, add an explicit check
6620 // to ensure the key is a smi must be added.
6621 if (key_not_smi != NULL) {
6622 __ JumpIfNotSmi(key, key_not_smi);
6623 } else {
6624 if (FLAG_debug_code) {
6625 __ AbortIfNotSmi(key);
6626 }
6627 }
6628
6629 // Key must be a smi and it must be in range.
6630 __ mov(untagged_key, key);
6631 __ SmiUntag(untagged_key);
6632 __ cmp(untagged_key, FieldOperand(elements, PixelArray::kLengthOffset));
6633 __ j(above_equal, out_of_range); // unsigned check handles negative keys.
6634
6635 // Value must be a smi.
6636 __ JumpIfNotSmi(value, value_not_smi);
6637 __ mov(untagged_value, value);
6638 __ SmiUntag(untagged_value);
6639
6640 { // Clamp the value to [0..255].
6641 NearLabel done;
6642 __ test(untagged_value, Immediate(0xFFFFFF00));
6643 __ j(zero, &done);
6644 __ setcc(negative, untagged_value); // 1 if negative, 0 if positive.
6645 __ dec_b(untagged_value); // 0 if negative, 255 if positive.
6646 __ bind(&done);
6647 }
6648
6649 __ mov(external_pointer,
6650 FieldOperand(elements, PixelArray::kExternalPointerOffset));
6651 __ mov_b(Operand(external_pointer, untagged_key, times_1, 0), untagged_value);
6652 __ ret(0); // Return value in eax.
6653 }
6654
6655
6656 void IncrementalMarkingRecordWriteStub::Generate(MacroAssembler* masm) { 6467 void IncrementalMarkingRecordWriteStub::Generate(MacroAssembler* masm) {
6657 if (IncrementalMarking::IsStopped()) { 6468 if (IncrementalMarking::IsStopped()) {
6658 __ ret(0); 6469 __ ret(0);
6659 } else { 6470 } else {
6660 __ nop(); 6471 __ nop();
6661 } 6472 }
6662 6473
6663 __ IncrementalMarkingRecordWriteHelper(object_, 6474 __ IncrementalMarkingRecordWriteHelper(object_,
6664 value_, 6475 value_,
6665 scratch_, 6476 scratch_,
6666 object_mode_, 6477 object_mode_,
6667 value_mode_, 6478 value_mode_,
6668 scratch_mode_); 6479 scratch_mode_);
6669 __ ret(0); 6480 __ ret(0);
6670 } 6481 }
6671 6482
6672 6483
6673 #undef __ 6484 #undef __
6674 6485
6675 } } // namespace v8::internal 6486 } } // namespace v8::internal
6676 6487
6677 #endif // V8_TARGET_ARCH_IA32 6488 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698