| Index: src/ia32/code-stubs-ia32.cc
|
| ===================================================================
|
| --- src/ia32/code-stubs-ia32.cc (revision 7180)
|
| +++ src/ia32/code-stubs-ia32.cc (working copy)
|
| @@ -2416,14 +2416,14 @@
|
|
|
|
|
| void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
|
| - NearLabel call_runtime;
|
| + ASSERT(op_ == Token::ADD);
|
| + NearLabel left_not_string, call_runtime;
|
|
|
| // Registers containing left and right operands respectively.
|
| Register left = edx;
|
| Register right = eax;
|
|
|
| // Test if left operand is a string.
|
| - NearLabel left_not_string;
|
| __ test(left, Immediate(kSmiTagMask));
|
| __ j(zero, &left_not_string);
|
| __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx);
|
| @@ -3430,7 +3430,7 @@
|
| __ test(edx, Immediate(kSmiTagMask));
|
| __ j(not_zero, &base_nonsmi);
|
|
|
| - // Optimized version when both exponent and base is a smi.
|
| + // Optimized version when both exponent and base are smis.
|
| Label powi;
|
| __ SmiUntag(edx);
|
| __ cvtsi2sd(xmm0, Operand(edx));
|
| @@ -3469,7 +3469,6 @@
|
| __ j(not_carry, &no_multiply);
|
| __ mulsd(xmm1, xmm0);
|
| __ bind(&no_multiply);
|
| - __ test(eax, Operand(eax));
|
| __ mulsd(xmm0, xmm0);
|
| __ j(not_zero, &while_true);
|
|
|
| @@ -3556,7 +3555,7 @@
|
| __ AllocateHeapNumber(ecx, eax, edx, &call_runtime);
|
| __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm1);
|
| __ mov(eax, ecx);
|
| - __ ret(2);
|
| + __ ret(2 * kPointerSize);
|
|
|
| __ bind(&call_runtime);
|
| __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
|
| @@ -4683,6 +4682,11 @@
|
| }
|
|
|
|
|
| +bool CEntryStub::NeedsImmovableCode() {
|
| + return false;
|
| +}
|
| +
|
| +
|
| void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
|
| __ Throw(eax);
|
| }
|
| @@ -5540,8 +5544,8 @@
|
| STATIC_ASSERT(Smi::kMaxValue == String::kMaxLength);
|
| // Handle exceptionally long strings in the runtime system.
|
| __ j(overflow, &string_add_runtime);
|
| - // Use the runtime system when adding two one character strings, as it
|
| - // contains optimizations for this specific case using the symbol table.
|
| + // Use the symbol table when adding two one character strings, as it
|
| + // helps later optimizations to return a symbol here.
|
| __ cmp(Operand(ebx), Immediate(Smi::FromInt(2)));
|
| __ j(not_equal, &longer_than_two);
|
|
|
| @@ -5958,6 +5962,8 @@
|
| // If entry is undefined no string with this hash can be found.
|
| __ cmp(candidate, Factory::undefined_value());
|
| __ j(equal, not_found);
|
| + __ cmp(candidate, Factory::null_value());
|
| + __ j(equal, &next_probe[i]);
|
|
|
| // If length is not 2 the string is not a candidate.
|
| __ cmp(FieldOperand(candidate, String::kLengthOffset),
|
| @@ -6326,59 +6332,6 @@
|
| }
|
|
|
|
|
| -void StringCharAtStub::Generate(MacroAssembler* masm) {
|
| - // Expects two arguments (object, index) on the stack:
|
| -
|
| - // Stack frame on entry.
|
| - // esp[0]: return address
|
| - // esp[4]: index
|
| - // esp[8]: object
|
| -
|
| - Register object = ebx;
|
| - Register index = eax;
|
| - Register scratch1 = ecx;
|
| - Register scratch2 = edx;
|
| - Register result = eax;
|
| -
|
| - __ pop(scratch1); // Return address.
|
| - __ pop(index);
|
| - __ pop(object);
|
| - __ push(scratch1);
|
| -
|
| - Label need_conversion;
|
| - Label index_out_of_range;
|
| - Label done;
|
| - StringCharAtGenerator generator(object,
|
| - index,
|
| - scratch1,
|
| - scratch2,
|
| - result,
|
| - &need_conversion,
|
| - &need_conversion,
|
| - &index_out_of_range,
|
| - STRING_INDEX_IS_NUMBER);
|
| - generator.GenerateFast(masm);
|
| - __ jmp(&done);
|
| -
|
| - __ bind(&index_out_of_range);
|
| - // When the index is out of range, the spec requires us to return
|
| - // the empty string.
|
| - __ Set(result, Immediate(Factory::empty_string()));
|
| - __ jmp(&done);
|
| -
|
| - __ bind(&need_conversion);
|
| - // Move smi zero into the result register, which will trigger
|
| - // conversion.
|
| - __ Set(result, Immediate(Smi::FromInt(0)));
|
| - __ jmp(&done);
|
| -
|
| - StubRuntimeCallHelper call_helper;
|
| - generator.GenerateSlow(masm, call_helper);
|
| -
|
| - __ bind(&done);
|
| - __ ret(0);
|
| -}
|
| -
|
| void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
|
| ASSERT(state_ == CompareIC::SMIS);
|
| NearLabel miss;
|
| @@ -6511,148 +6464,6 @@
|
| }
|
|
|
|
|
| -// Loads a indexed element from a pixel array.
|
| -void GenerateFastPixelArrayLoad(MacroAssembler* masm,
|
| - Register receiver,
|
| - Register key,
|
| - Register elements,
|
| - Register untagged_key,
|
| - Register result,
|
| - Label* not_pixel_array,
|
| - Label* key_not_smi,
|
| - Label* out_of_range) {
|
| - // Register use:
|
| - // receiver - holds the receiver and is unchanged.
|
| - // key - holds the key and is unchanged (must be a smi).
|
| - // elements - is set to the the receiver's element if
|
| - // the receiver doesn't have a pixel array or the
|
| - // key is not a smi, otherwise it's the elements'
|
| - // external pointer.
|
| - // untagged_key - is set to the untagged key
|
| -
|
| - // Some callers already have verified that the key is a smi. key_not_smi is
|
| - // set to NULL as a sentinel for that case. Otherwise, add an explicit check
|
| - // to ensure the key is a smi must be added.
|
| - if (key_not_smi != NULL) {
|
| - __ JumpIfNotSmi(key, key_not_smi);
|
| - } else {
|
| - if (FLAG_debug_code) {
|
| - __ AbortIfNotSmi(key);
|
| - }
|
| - }
|
| - __ mov(untagged_key, key);
|
| - __ SmiUntag(untagged_key);
|
| -
|
| - __ mov(elements, FieldOperand(receiver, JSObject::kElementsOffset));
|
| - // By passing NULL as not_pixel_array, callers signal that they have already
|
| - // verified that the receiver has pixel array elements.
|
| - if (not_pixel_array != NULL) {
|
| - __ CheckMap(elements, Factory::pixel_array_map(), not_pixel_array, true);
|
| - } else {
|
| - if (FLAG_debug_code) {
|
| - // Map check should have already made sure that elements is a pixel array.
|
| - __ cmp(FieldOperand(elements, HeapObject::kMapOffset),
|
| - Immediate(Factory::pixel_array_map()));
|
| - __ Assert(equal, "Elements isn't a pixel array");
|
| - }
|
| - }
|
| -
|
| - // Key must be in range.
|
| - __ cmp(untagged_key, FieldOperand(elements, PixelArray::kLengthOffset));
|
| - __ j(above_equal, out_of_range); // unsigned check handles negative keys.
|
| -
|
| - // Perform the indexed load and tag the result as a smi.
|
| - __ mov(elements, FieldOperand(elements, PixelArray::kExternalPointerOffset));
|
| - __ movzx_b(result, Operand(elements, untagged_key, times_1, 0));
|
| - __ SmiTag(result);
|
| - __ ret(0);
|
| -}
|
| -
|
| -
|
| -// Stores an indexed element into a pixel array, clamping the stored value.
|
| -void GenerateFastPixelArrayStore(MacroAssembler* masm,
|
| - Register receiver,
|
| - Register key,
|
| - Register value,
|
| - Register elements,
|
| - Register scratch1,
|
| - bool load_elements_from_receiver,
|
| - Label* key_not_smi,
|
| - Label* value_not_smi,
|
| - Label* not_pixel_array,
|
| - Label* out_of_range) {
|
| - // Register use:
|
| - // receiver - holds the receiver and is unchanged unless the
|
| - // store succeeds.
|
| - // key - holds the key (must be a smi) and is unchanged.
|
| - // value - holds the value (must be a smi) and is unchanged.
|
| - // elements - holds the element object of the receiver on entry if
|
| - // load_elements_from_receiver is false, otherwise used
|
| - // internally to store the pixel arrays elements and
|
| - // external array pointer.
|
| - //
|
| - // receiver, key and value remain unmodified until it's guaranteed that the
|
| - // store will succeed.
|
| - Register external_pointer = elements;
|
| - Register untagged_key = scratch1;
|
| - Register untagged_value = receiver; // Only set once success guaranteed.
|
| -
|
| - // Fetch the receiver's elements if the caller hasn't already done so.
|
| - if (load_elements_from_receiver) {
|
| - __ mov(elements, FieldOperand(receiver, JSObject::kElementsOffset));
|
| - }
|
| -
|
| - // By passing NULL as not_pixel_array, callers signal that they have already
|
| - // verified that the receiver has pixel array elements.
|
| - if (not_pixel_array != NULL) {
|
| - __ CheckMap(elements, Factory::pixel_array_map(), not_pixel_array, true);
|
| - } else {
|
| - if (FLAG_debug_code) {
|
| - // Map check should have already made sure that elements is a pixel array.
|
| - __ cmp(FieldOperand(elements, HeapObject::kMapOffset),
|
| - Immediate(Factory::pixel_array_map()));
|
| - __ Assert(equal, "Elements isn't a pixel array");
|
| - }
|
| - }
|
| -
|
| - // Some callers already have verified that the key is a smi. key_not_smi is
|
| - // set to NULL as a sentinel for that case. Otherwise, add an explicit check
|
| - // to ensure the key is a smi must be added.
|
| - if (key_not_smi != NULL) {
|
| - __ JumpIfNotSmi(key, key_not_smi);
|
| - } else {
|
| - if (FLAG_debug_code) {
|
| - __ AbortIfNotSmi(key);
|
| - }
|
| - }
|
| -
|
| - // Key must be a smi and it must be in range.
|
| - __ mov(untagged_key, key);
|
| - __ SmiUntag(untagged_key);
|
| - __ cmp(untagged_key, FieldOperand(elements, PixelArray::kLengthOffset));
|
| - __ j(above_equal, out_of_range); // unsigned check handles negative keys.
|
| -
|
| - // Value must be a smi.
|
| - __ JumpIfNotSmi(value, value_not_smi);
|
| - __ mov(untagged_value, value);
|
| - __ SmiUntag(untagged_value);
|
| -
|
| - { // Clamp the value to [0..255].
|
| - NearLabel done;
|
| - __ test(untagged_value, Immediate(0xFFFFFF00));
|
| - __ j(zero, &done);
|
| - __ setcc(negative, untagged_value); // 1 if negative, 0 if positive.
|
| - __ dec_b(untagged_value); // 0 if negative, 255 if positive.
|
| - __ bind(&done);
|
| - }
|
| -
|
| - __ mov(external_pointer,
|
| - FieldOperand(elements, PixelArray::kExternalPointerOffset));
|
| - __ mov_b(Operand(external_pointer, untagged_key, times_1, 0), untagged_value);
|
| - __ ret(0); // Return value in eax.
|
| -}
|
| -
|
| -
|
| void IncrementalMarkingRecordWriteStub::Generate(MacroAssembler* masm) {
|
| if (IncrementalMarking::IsStopped()) {
|
| __ ret(0);
|
|
|