| Index: src/ia32/code-stubs-ia32.cc
|
| diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
|
| index 7cf9b44bc8d109fb5533b567bd2dbf16d699baf8..5789f49216f7a84feb65d87a5c85884a784dcbc4 100644
|
| --- a/src/ia32/code-stubs-ia32.cc
|
| +++ b/src/ia32/code-stubs-ia32.cc
|
| @@ -43,6 +43,16 @@ namespace v8 {
|
| namespace internal {
|
|
|
|
|
| +void ToNumberStub::InitializeInterfaceDescriptor(
|
| + Isolate* isolate,
|
| + CodeStubInterfaceDescriptor* descriptor) {
|
| + static Register registers[] = { eax };
|
| + descriptor->register_param_count_ = 1;
|
| + descriptor->register_params_ = registers;
|
| + descriptor->deoptimization_handler_ = NULL;
|
| +}
|
| +
|
| +
|
| void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
|
| Isolate* isolate,
|
| CodeStubInterfaceDescriptor* descriptor) {
|
| @@ -262,6 +272,17 @@ void StoreGlobalStub::InitializeInterfaceDescriptor(
|
| }
|
|
|
|
|
| +void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
|
| + Isolate* isolate,
|
| + CodeStubInterfaceDescriptor* descriptor) {
|
| + static Register registers[] = { eax, ebx, ecx, edx };
|
| + descriptor->register_param_count_ = 4;
|
| + descriptor->register_params_ = registers;
|
| + descriptor->deoptimization_handler_ =
|
| + FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
|
| +}
|
| +
|
| +
|
| #define __ ACCESS_MASM(masm)
|
|
|
|
|
| @@ -289,27 +310,6 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
|
| }
|
|
|
|
|
| -void ToNumberStub::Generate(MacroAssembler* masm) {
|
| - // The ToNumber stub takes one argument in eax.
|
| - Label check_heap_number, call_builtin;
|
| - __ JumpIfNotSmi(eax, &check_heap_number, Label::kNear);
|
| - __ ret(0);
|
| -
|
| - __ bind(&check_heap_number);
|
| - __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
|
| - Factory* factory = masm->isolate()->factory();
|
| - __ cmp(ebx, Immediate(factory->heap_number_map()));
|
| - __ j(not_equal, &call_builtin, Label::kNear);
|
| - __ ret(0);
|
| -
|
| - __ bind(&call_builtin);
|
| - __ pop(ecx); // Pop return address.
|
| - __ push(eax);
|
| - __ push(ecx); // Push return address.
|
| - __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
|
| -}
|
| -
|
| -
|
| void FastNewClosureStub::Generate(MacroAssembler* masm) {
|
| // Create a new closure from the given function info in new
|
| // space. Set the context to the current context in esi.
|
| @@ -665,7 +665,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
|
|
|
| MemOperand mantissa_operand(MemOperand(input_reg, double_offset));
|
| MemOperand exponent_operand(MemOperand(input_reg,
|
| - double_offset + kPointerSize));
|
| + double_offset + kDoubleSize / 2));
|
|
|
| Register scratch1;
|
| {
|
| @@ -1342,8 +1342,8 @@ void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
|
| __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx);
|
| __ j(above_equal, &call_runtime, Label::kNear);
|
|
|
| - StringAddStub string_add_stub((StringAddFlags)
|
| - (ERECT_FRAME | NO_STRING_CHECK_IN_STUB));
|
| + StringAddStub string_add_stub(
|
| + (StringAddFlags)(STRING_ADD_CHECK_NONE | STRING_ADD_ERECT_FRAME));
|
| GenerateRegisterArgsPush(masm);
|
| __ TailCallStub(&string_add_stub);
|
|
|
| @@ -1988,8 +1988,8 @@ void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
|
| __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx);
|
| __ j(above_equal, &left_not_string, Label::kNear);
|
|
|
| - StringAddStub string_add_left_stub((StringAddFlags)
|
| - (ERECT_FRAME | NO_STRING_CHECK_LEFT_IN_STUB));
|
| + StringAddStub string_add_left_stub(
|
| + (StringAddFlags)(STRING_ADD_CHECK_RIGHT | STRING_ADD_ERECT_FRAME));
|
| GenerateRegisterArgsPush(masm);
|
| __ TailCallStub(&string_add_left_stub);
|
|
|
| @@ -1999,8 +1999,8 @@ void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
|
| __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx);
|
| __ j(above_equal, &call_runtime, Label::kNear);
|
|
|
| - StringAddStub string_add_right_stub((StringAddFlags)
|
| - (ERECT_FRAME | NO_STRING_CHECK_RIGHT_IN_STUB));
|
| + StringAddStub string_add_right_stub(
|
| + (StringAddFlags)(STRING_ADD_CHECK_LEFT | STRING_ADD_ERECT_FRAME));
|
| GenerateRegisterArgsPush(masm);
|
| __ TailCallStub(&string_add_right_stub);
|
|
|
| @@ -3961,7 +3961,6 @@ void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
|
| Register result,
|
| Register scratch1,
|
| Register scratch2,
|
| - bool object_is_smi,
|
| Label* not_found) {
|
| // Use of registers. Register result is used as a temporary.
|
| Register number_string_cache = result;
|
| @@ -3986,52 +3985,46 @@ void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
|
| // Heap::GetNumberStringCache.
|
| Label smi_hash_calculated;
|
| Label load_result_from_cache;
|
| - if (object_is_smi) {
|
| - __ mov(scratch, object);
|
| - __ SmiUntag(scratch);
|
| + Label not_smi;
|
| + STATIC_ASSERT(kSmiTag == 0);
|
| + __ JumpIfNotSmi(object, ¬_smi, Label::kNear);
|
| + __ mov(scratch, object);
|
| + __ SmiUntag(scratch);
|
| + __ jmp(&smi_hash_calculated, Label::kNear);
|
| + __ bind(¬_smi);
|
| + __ cmp(FieldOperand(object, HeapObject::kMapOffset),
|
| + masm->isolate()->factory()->heap_number_map());
|
| + __ j(not_equal, not_found);
|
| + STATIC_ASSERT(8 == kDoubleSize);
|
| + __ mov(scratch, FieldOperand(object, HeapNumber::kValueOffset));
|
| + __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4));
|
| + // Object is heap number and hash is now in scratch. Calculate cache index.
|
| + __ and_(scratch, mask);
|
| + Register index = scratch;
|
| + Register probe = mask;
|
| + __ mov(probe,
|
| + FieldOperand(number_string_cache,
|
| + index,
|
| + times_twice_pointer_size,
|
| + FixedArray::kHeaderSize));
|
| + __ JumpIfSmi(probe, not_found);
|
| + if (CpuFeatures::IsSupported(SSE2)) {
|
| + CpuFeatureScope fscope(masm, SSE2);
|
| + __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
|
| + __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset));
|
| + __ ucomisd(xmm0, xmm1);
|
| } else {
|
| - Label not_smi;
|
| - STATIC_ASSERT(kSmiTag == 0);
|
| - __ JumpIfNotSmi(object, ¬_smi, Label::kNear);
|
| - __ mov(scratch, object);
|
| - __ SmiUntag(scratch);
|
| - __ jmp(&smi_hash_calculated, Label::kNear);
|
| - __ bind(¬_smi);
|
| - __ cmp(FieldOperand(object, HeapObject::kMapOffset),
|
| - masm->isolate()->factory()->heap_number_map());
|
| - __ j(not_equal, not_found);
|
| - STATIC_ASSERT(8 == kDoubleSize);
|
| - __ mov(scratch, FieldOperand(object, HeapNumber::kValueOffset));
|
| - __ xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4));
|
| - // Object is heap number and hash is now in scratch. Calculate cache index.
|
| - __ and_(scratch, mask);
|
| - Register index = scratch;
|
| - Register probe = mask;
|
| - __ mov(probe,
|
| - FieldOperand(number_string_cache,
|
| - index,
|
| - times_twice_pointer_size,
|
| - FixedArray::kHeaderSize));
|
| - __ JumpIfSmi(probe, not_found);
|
| - if (CpuFeatures::IsSupported(SSE2)) {
|
| - CpuFeatureScope fscope(masm, SSE2);
|
| - __ movdbl(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
|
| - __ movdbl(xmm1, FieldOperand(probe, HeapNumber::kValueOffset));
|
| - __ ucomisd(xmm0, xmm1);
|
| - } else {
|
| - __ fld_d(FieldOperand(object, HeapNumber::kValueOffset));
|
| - __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset));
|
| - __ FCmp();
|
| - }
|
| - __ j(parity_even, not_found); // Bail out if NaN is involved.
|
| - __ j(not_equal, not_found); // The cache did not contain this value.
|
| - __ jmp(&load_result_from_cache, Label::kNear);
|
| + __ fld_d(FieldOperand(object, HeapNumber::kValueOffset));
|
| + __ fld_d(FieldOperand(probe, HeapNumber::kValueOffset));
|
| + __ FCmp();
|
| }
|
| + __ j(parity_even, not_found); // Bail out if NaN is involved.
|
| + __ j(not_equal, not_found); // The cache did not contain this value.
|
| + __ jmp(&load_result_from_cache, Label::kNear);
|
|
|
| __ bind(&smi_hash_calculated);
|
| // Object is smi and hash is now in scratch. Calculate cache index.
|
| __ and_(scratch, mask);
|
| - Register index = scratch;
|
| // Check if the entry is the smi we are looking for.
|
| __ cmp(object,
|
| FieldOperand(number_string_cache,
|
| @@ -4058,7 +4051,7 @@ void NumberToStringStub::Generate(MacroAssembler* masm) {
|
| __ mov(ebx, Operand(esp, kPointerSize));
|
|
|
| // Generate code to lookup number in the number string cache.
|
| - GenerateLookupNumberStringCache(masm, ebx, eax, ecx, edx, false, &runtime);
|
| + GenerateLookupNumberStringCache(masm, ebx, eax, ecx, edx, &runtime);
|
| __ ret(1 * kPointerSize);
|
|
|
| __ bind(&runtime);
|
| @@ -4101,9 +4094,9 @@ static void BranchIfNotInternalizedString(MacroAssembler* masm,
|
| __ JumpIfSmi(object, label);
|
| __ mov(scratch, FieldOperand(object, HeapObject::kMapOffset));
|
| __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
|
| - __ and_(scratch, kIsInternalizedMask | kIsNotStringMask);
|
| - __ cmp(scratch, kInternalizedTag | kStringTag);
|
| - __ j(not_equal, label);
|
| + STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
|
| + __ test(scratch, Immediate(kIsNotStringMask | kIsNotInternalizedMask));
|
| + __ j(not_zero, label);
|
| }
|
|
|
|
|
| @@ -5372,7 +5365,11 @@ void StringAddStub::Generate(MacroAssembler* masm) {
|
| __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument.
|
|
|
| // Make sure that both arguments are strings if not known in advance.
|
| - if ((flags_ & NO_STRING_ADD_FLAGS) != 0) {
|
| + // Otherwise, at least one of the arguments is definitely a string,
|
| + // and we convert the one that is not known to be a string.
|
| + if ((flags_ & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
|
| + ASSERT((flags_ & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT);
|
| + ASSERT((flags_ & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT);
|
| __ JumpIfSmi(eax, &call_runtime);
|
| __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ebx);
|
| __ j(above_equal, &call_runtime);
|
| @@ -5381,20 +5378,16 @@ void StringAddStub::Generate(MacroAssembler* masm) {
|
| __ JumpIfSmi(edx, &call_runtime);
|
| __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ebx);
|
| __ j(above_equal, &call_runtime);
|
| - } else {
|
| - // Here at least one of the arguments is definitely a string.
|
| - // We convert the one that is not known to be a string.
|
| - if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) {
|
| - ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0);
|
| - GenerateConvertArgument(masm, 2 * kPointerSize, eax, ebx, ecx, edi,
|
| - &call_builtin);
|
| - builtin_id = Builtins::STRING_ADD_RIGHT;
|
| - } else if ((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) == 0) {
|
| - ASSERT((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) != 0);
|
| - GenerateConvertArgument(masm, 1 * kPointerSize, edx, ebx, ecx, edi,
|
| - &call_builtin);
|
| - builtin_id = Builtins::STRING_ADD_LEFT;
|
| - }
|
| + } else if ((flags_ & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
|
| + ASSERT((flags_ & STRING_ADD_CHECK_RIGHT) == 0);
|
| + GenerateConvertArgument(masm, 2 * kPointerSize, eax, ebx, ecx, edi,
|
| + &call_builtin);
|
| + builtin_id = Builtins::STRING_ADD_RIGHT;
|
| + } else if ((flags_ & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) {
|
| + ASSERT((flags_ & STRING_ADD_CHECK_LEFT) == 0);
|
| + GenerateConvertArgument(masm, 1 * kPointerSize, edx, ebx, ecx, edi,
|
| + &call_builtin);
|
| + builtin_id = Builtins::STRING_ADD_LEFT;
|
| }
|
|
|
| // Both arguments are strings.
|
| @@ -5680,7 +5673,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
|
| __ Drop(2);
|
| // Just jump to runtime to add the two strings.
|
| __ bind(&call_runtime);
|
| - if ((flags_ & ERECT_FRAME) != 0) {
|
| + if ((flags_ & STRING_ADD_ERECT_FRAME) != 0) {
|
| GenerateRegisterArgsPop(masm, ecx);
|
| // Build a frame
|
| {
|
| @@ -5695,7 +5688,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
|
|
|
| if (call_builtin.is_linked()) {
|
| __ bind(&call_builtin);
|
| - if ((flags_ & ERECT_FRAME) != 0) {
|
| + if ((flags_ & STRING_ADD_ERECT_FRAME) != 0) {
|
| GenerateRegisterArgsPop(masm, ecx);
|
| // Build a frame
|
| {
|
| @@ -5748,7 +5741,6 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
|
| scratch1,
|
| scratch2,
|
| scratch3,
|
| - false,
|
| ¬_cached);
|
| __ mov(arg, scratch1);
|
| __ mov(Operand(esp, stack_offset), arg);
|
| @@ -6598,14 +6590,10 @@ void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) {
|
| __ mov(tmp2, FieldOperand(right, HeapObject::kMapOffset));
|
| __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset));
|
| __ movzx_b(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset));
|
| - STATIC_ASSERT(kInternalizedTag != 0);
|
| - __ and_(tmp1, Immediate(kIsNotStringMask | kIsInternalizedMask));
|
| - __ cmpb(tmp1, kInternalizedTag | kStringTag);
|
| - __ j(not_equal, &miss, Label::kNear);
|
| -
|
| - __ and_(tmp2, Immediate(kIsNotStringMask | kIsInternalizedMask));
|
| - __ cmpb(tmp2, kInternalizedTag | kStringTag);
|
| - __ j(not_equal, &miss, Label::kNear);
|
| + STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
|
| + __ or_(tmp1, tmp2);
|
| + __ test(tmp1, Immediate(kIsNotStringMask | kIsNotInternalizedMask));
|
| + __ j(not_zero, &miss, Label::kNear);
|
|
|
| // Internalized strings are compared by identity.
|
| Label done;
|
| @@ -6644,7 +6632,6 @@ void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) {
|
|
|
| // Check that both operands are unique names. This leaves the instance
|
| // types loaded in tmp1 and tmp2.
|
| - STATIC_ASSERT(kInternalizedTag != 0);
|
| __ mov(tmp1, FieldOperand(left, HeapObject::kMapOffset));
|
| __ mov(tmp2, FieldOperand(right, HeapObject::kMapOffset));
|
| __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset));
|
| @@ -6720,10 +6707,10 @@ void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
|
| // also know they are both strings.
|
| if (equality) {
|
| Label do_compare;
|
| - STATIC_ASSERT(kInternalizedTag != 0);
|
| - __ and_(tmp1, tmp2);
|
| - __ test(tmp1, Immediate(kIsInternalizedMask));
|
| - __ j(zero, &do_compare, Label::kNear);
|
| + STATIC_ASSERT(kInternalizedTag == 0);
|
| + __ or_(tmp1, tmp2);
|
| + __ test(tmp1, Immediate(kIsNotInternalizedMask));
|
| + __ j(not_zero, &do_compare, Label::kNear);
|
| // Make sure eax is non-zero. At this point input operands are
|
| // guaranteed to be non-zero.
|
| ASSERT(right.is(eax));
|
|
|