Clean up after r16292 (disable optimization for StringWrappers).

R=jochen@chromium.org
BUG=v8:2855

Review URL: https://codereview.chromium.org/22891028

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16677 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2013-09-12 10:55:57 +00:00
parent 6a558d107a
commit 996813cca2
9 changed files with 65 additions and 87 deletions

View File

@ -5790,7 +5790,6 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
__ b(lt, &done);
// Check the number to string cache.
Label not_cached;
__ bind(&not_string);
// Puts the cached result into scratch1.
NumberToStringStub::GenerateLookupNumberStringCache(masm,
@ -5799,26 +5798,9 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
scratch2,
scratch3,
scratch4,
&not_cached);
slow);
__ mov(arg, scratch1);
__ str(arg, MemOperand(sp, stack_offset));
__ jmp(&done);
// Check if the argument is a safe string wrapper.
__ bind(&not_cached);
__ JumpIfSmi(arg, slow);
__ CompareObjectType(
arg, scratch1, scratch2, JS_VALUE_TYPE); // map -> scratch1.
__ b(ne, slow);
__ ldrb(scratch2, FieldMemOperand(scratch1, Map::kBitField2Offset));
__ and_(scratch2,
scratch2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
__ cmp(scratch2,
Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
__ b(ne, slow);
__ ldr(arg, FieldMemOperand(arg, JSValue::kValueOffset));
__ str(arg, MemOperand(sp, stack_offset));
__ bind(&done);
}

View File

@ -3007,7 +3007,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label materialize_true, materialize_false, skip_lookup;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
@ -3019,7 +3019,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
__ ldrb(ip, FieldMemOperand(r1, Map::kBitField2Offset));
__ tst(ip, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
__ b(ne, if_true);
__ b(ne, &skip_lookup);
// Check for fast case object. Generate false result for slow case object.
__ ldr(r2, FieldMemOperand(r0, JSObject::kPropertiesOffset));
@ -3065,6 +3065,14 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ b(ne, &loop);
__ bind(&done);
// Set the bit in the map to indicate that there is no local valueOf field.
__ ldrb(r2, FieldMemOperand(r1, Map::kBitField2Offset));
__ orr(r2, r2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
__ strb(r2, FieldMemOperand(r1, Map::kBitField2Offset));
__ bind(&skip_lookup);
// If a valueOf property is not found on the object check that its
// prototype is the un-modified String prototype. If not result is false.
__ ldr(r2, FieldMemOperand(r1, Map::kPrototypeOffset));
@ -3074,11 +3082,9 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ ldr(r3, FieldMemOperand(r3, GlobalObject::kNativeContextOffset));
__ ldr(r3, ContextOperand(r3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
__ cmp(r2, r3);
__ b(ne, if_false);
__ jmp(if_true);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(eq, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}

View File

@ -5515,7 +5515,6 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
__ j(below, &done);
// Check the number to string cache.
Label not_cached;
__ bind(&not_string);
// Puts the cached result into scratch1.
NumberToStringStub::GenerateLookupNumberStringCache(masm,
@ -5523,22 +5522,9 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
scratch1,
scratch2,
scratch3,
&not_cached);
slow);
__ mov(arg, scratch1);
__ mov(Operand(esp, stack_offset), arg);
__ jmp(&done);
// Check if the argument is a safe string wrapper.
__ bind(&not_cached);
__ JumpIfSmi(arg, slow);
__ CmpObjectType(arg, JS_VALUE_TYPE, scratch1); // map -> scratch1.
__ j(not_equal, slow);
__ test_b(FieldOperand(scratch1, Map::kBitField2Offset),
1 << Map::kStringWrapperSafeForDefaultValueOf);
__ j(zero, slow);
__ mov(arg, FieldOperand(arg, JSValue::kValueOffset));
__ mov(Operand(esp, stack_offset), arg);
__ bind(&done);
}

View File

@ -2956,7 +2956,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label materialize_true, materialize_false, skip_lookup;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
@ -2970,7 +2970,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
__ test_b(FieldOperand(ebx, Map::kBitField2Offset),
1 << Map::kStringWrapperSafeForDefaultValueOf);
__ j(not_zero, if_true);
__ j(not_zero, &skip_lookup);
// Check for fast case object. Return false for slow case objects.
__ mov(ecx, FieldOperand(eax, JSObject::kPropertiesOffset));
@ -3013,9 +3013,15 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ bind(&done);
// Set the bit in the map to indicate that there is no local valueOf field.
__ or_(FieldOperand(ebx, Map::kBitField2Offset),
Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
// Reload map as register ebx was used as temporary above.
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
__ bind(&skip_lookup);
// If a valueOf property is not found on the object check that its
// prototype is the un-modified String prototype. If not result is false.
__ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
@ -3027,10 +3033,9 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ cmp(ecx,
ContextOperand(edx,
Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
__ j(not_equal, if_false);
__ jmp(if_true);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(equal, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}

View File

@ -5861,7 +5861,6 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
__ Branch(&done, lt, scratch1, Operand(FIRST_NONSTRING_TYPE));
// Check the number to string cache.
Label not_cached;
__ bind(&not_string);
// Puts the cached result into scratch1.
NumberToStringStub::GenerateLookupNumberStringCache(masm,
@ -5870,23 +5869,9 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
scratch2,
scratch3,
scratch4,
&not_cached);
slow);
__ mov(arg, scratch1);
__ sw(arg, MemOperand(sp, stack_offset));
__ jmp(&done);
// Check if the argument is a safe string wrapper.
__ bind(&not_cached);
__ JumpIfSmi(arg, slow);
__ GetObjectType(arg, scratch1, scratch2); // map -> scratch1.
__ Branch(slow, ne, scratch2, Operand(JS_VALUE_TYPE));
__ lbu(scratch2, FieldMemOperand(scratch1, Map::kBitField2Offset));
__ li(scratch4, 1 << Map::kStringWrapperSafeForDefaultValueOf);
__ And(scratch2, scratch2, scratch4);
__ Branch(slow, ne, scratch2, Operand(scratch4));
__ lw(arg, FieldMemOperand(arg, JSValue::kValueOffset));
__ sw(arg, MemOperand(sp, stack_offset));
__ bind(&done);
}

View File

@ -3028,7 +3028,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label materialize_true, materialize_false, skip_lookup;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
@ -3040,7 +3040,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
__ lbu(t0, FieldMemOperand(a1, Map::kBitField2Offset));
__ And(t0, t0, 1 << Map::kStringWrapperSafeForDefaultValueOf);
__ Branch(if_true, ne, t0, Operand(zero_reg));
__ Branch(&skip_lookup, ne, t0, Operand(zero_reg));
// Check for fast case object. Generate false result for slow case object.
__ lw(a2, FieldMemOperand(v0, JSObject::kPropertiesOffset));
@ -3086,6 +3086,14 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ Branch(&loop, ne, t0, Operand(a2));
__ bind(&done);
// Set the bit in the map to indicate that there is no local valueOf field.
__ lbu(a2, FieldMemOperand(a1, Map::kBitField2Offset));
__ Or(a2, a2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
__ sb(a2, FieldMemOperand(a1, Map::kBitField2Offset));
__ bind(&skip_lookup);
// If a valueOf property is not found on the object check that its
// prototype is the un-modified String prototype. If not result is false.
__ lw(a2, FieldMemOperand(a1, Map::kPrototypeOffset));
@ -3094,11 +3102,9 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ lw(a3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
__ lw(a3, FieldMemOperand(a3, GlobalObject::kNativeContextOffset));
__ lw(a3, ContextOperand(a3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
__ Branch(if_false, ne, a2, Operand(a3));
__ jmp(if_true);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(eq, a2, Operand(a3), if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}

View File

@ -4644,7 +4644,6 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
__ j(below, &done);
// Check the number to string cache.
Label not_cached;
__ bind(&not_string);
// Puts the cached result into scratch1.
NumberToStringStub::GenerateLookupNumberStringCache(masm,
@ -4652,22 +4651,9 @@ void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
scratch1,
scratch2,
scratch3,
&not_cached);
slow);
__ movq(arg, scratch1);
__ movq(Operand(rsp, stack_offset), arg);
__ jmp(&done);
// Check if the argument is a safe string wrapper.
__ bind(&not_cached);
__ JumpIfSmi(arg, slow);
__ CmpObjectType(arg, JS_VALUE_TYPE, scratch1); // map -> scratch1.
__ j(not_equal, slow);
__ testb(FieldOperand(scratch1, Map::kBitField2Offset),
Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
__ j(zero, slow);
__ movq(arg, FieldOperand(arg, JSValue::kValueOffset));
__ movq(Operand(rsp, stack_offset), arg);
__ bind(&done);
}

View File

@ -2935,7 +2935,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label materialize_true, materialize_false, skip_lookup;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
@ -2949,7 +2949,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
__ testb(FieldOperand(rbx, Map::kBitField2Offset),
Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
__ j(not_zero, if_true);
__ j(not_zero, &skip_lookup);
// Check for fast case object. Generate false result for slow case object.
__ movq(rcx, FieldOperand(rax, JSObject::kPropertiesOffset));
@ -2991,9 +2991,16 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ j(not_equal, &loop);
__ bind(&done);
// Set the bit in the map to indicate that there is no local valueOf field.
__ or_(FieldOperand(rbx, Map::kBitField2Offset),
Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
// Reload map as register rbx was used as temporary above.
__ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
__ bind(&skip_lookup);
// If a valueOf property is not found on the object check that its
// prototype is the un-modified String prototype. If not result is false.
__ movq(rcx, FieldOperand(rbx, Map::kPrototypeOffset));
@ -3004,10 +3011,9 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
__ movq(rdx, FieldOperand(rdx, GlobalObject::kNativeContextOffset));
__ cmpq(rcx,
ContextOperand(rdx, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
__ j(not_equal, if_false);
__ jmp(if_true);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(equal, if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}

View File

@ -39,3 +39,19 @@ for (var i = 0; i < 4; ++i) {
}
assertEquals(expected, "" + foo("hello"));
}
// Make sure we look up "valueOf" only once.
var count = 0;
var x = new String("foo");
Object.defineProperty(x, "valueOf",
{ get: function() {
count++;
return function() {
return 11;
}
}
});
for (var i = 0; i < 3; i++) {
assertEquals("11", "" + x);
assertEquals(i + 1, count);
}