Chromium Code Reviews| Index: src/ic.cc |
| diff --git a/src/ic.cc b/src/ic.cc |
| index 99eb21fa2e698caee89005ea9655542832cc5bbe..bfda567874096d03a79561a8b5273b7925f42bdc 100644 |
| --- a/src/ic.cc |
| +++ b/src/ic.cc |
| @@ -1990,6 +1990,7 @@ const char* TRBinaryOpIC::GetName(TypeInfo type_info) { |
| case INT32: return "Int32s"; |
| case HEAP_NUMBER: return "HeapNumbers"; |
| case ODDBALL: return "Oddball"; |
| + case BOTH_STRING: return "BothStrings"; |
| case STRING: return "Strings"; |
| case GENERIC: return "Generic"; |
| default: return "Invalid"; |
| @@ -2005,6 +2006,7 @@ TRBinaryOpIC::State TRBinaryOpIC::ToState(TypeInfo type_info) { |
| case INT32: |
| case HEAP_NUMBER: |
| case ODDBALL: |
| + case BOTH_STRING: |
| case STRING: |
| return MONOMORPHIC; |
| case GENERIC: |
| @@ -2019,12 +2021,17 @@ TRBinaryOpIC::TypeInfo TRBinaryOpIC::JoinTypes(TRBinaryOpIC::TypeInfo x, |
| TRBinaryOpIC::TypeInfo y) { |
| if (x == UNINITIALIZED) return y; |
| if (y == UNINITIALIZED) return x; |
| - if (x == STRING && y == STRING) return STRING; |
| - if (x == STRING || y == STRING) return GENERIC; |
| + if (x == y) return x; |
| + if (x == BOTH_STRING && y == STRING) return STRING; |
| + if (x == STRING && y == BOTH_STRING) return STRING; |
| + if (x == STRING || x == BOTH_STRING || y == STRING || y == BOTH_STRING) { |
| + return GENERIC; |
| + } |
|
fschneider
2011/04/14 10:26:47
I think this is correct. Personally I like the app
Vitaly Repeshko
2011/04/14 21:07:18
TRBinaryOpIC::TypeInfo has to stay dense for now b
|
| if (x >= y) return x; |
|
fschneider
2011/04/14 10:26:47
Maybe have x > y here since you handle == cases al
Vitaly Repeshko
2011/04/14 21:07:18
Done.
|
| return y; |
| } |
| + |
| TRBinaryOpIC::TypeInfo TRBinaryOpIC::GetTypeInfo(Handle<Object> left, |
| Handle<Object> right) { |
| ::v8::internal::TypeInfo left_type = |
| @@ -2046,9 +2053,11 @@ TRBinaryOpIC::TypeInfo TRBinaryOpIC::GetTypeInfo(Handle<Object> left, |
| return HEAP_NUMBER; |
| } |
| - if (left_type.IsString() || right_type.IsString()) { |
| - // Patching for fast string ADD makes sense even if only one of the |
| - // arguments is a string. |
| + // Patching for fast string ADD makes sense even if only one of the |
| + // arguments is a string. |
| + if (left_type.IsString()) { |
| + return right_type.IsString() ? BOTH_STRING : STRING; |
| + } else if (right_type.IsString()) { |
| return STRING; |
| } |
| @@ -2081,7 +2090,8 @@ RUNTIME_FUNCTION(MaybeObject*, TypeRecordingBinaryOp_Patch) { |
| TRBinaryOpIC::TypeInfo type = TRBinaryOpIC::GetTypeInfo(left, right); |
| type = TRBinaryOpIC::JoinTypes(type, previous_type); |
| TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED; |
| - if (type == TRBinaryOpIC::STRING && op != Token::ADD) { |
| + if ((type == TRBinaryOpIC::STRING || type == TRBinaryOpIC::BOTH_STRING) && |
| + op != Token::ADD) { |
| type = TRBinaryOpIC::GENERIC; |
| } |
| if (type == TRBinaryOpIC::SMI && |
| @@ -2097,8 +2107,7 @@ RUNTIME_FUNCTION(MaybeObject*, TypeRecordingBinaryOp_Patch) { |
| result_type = TRBinaryOpIC::INT32; |
| } |
| } |
| - if (type == TRBinaryOpIC::INT32 && |
| - previous_type == TRBinaryOpIC::INT32) { |
| + if (type == TRBinaryOpIC::INT32 && previous_type == TRBinaryOpIC::INT32) { |
| // We must be here because an operation on two INT32 types overflowed. |
| result_type = TRBinaryOpIC::HEAP_NUMBER; |
| } |