| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 mode_, | 1125 mode_, |
| 1126 NO_SMI_CODE_IN_STUB, | 1126 NO_SMI_CODE_IN_STUB, |
| 1127 TypeInfo::Combine(left_info_, right_info_)); | 1127 TypeInfo::Combine(left_info_, right_info_)); |
| 1128 stub.GenerateCall(masm_, left_, right_); | 1128 stub.GenerateCall(masm_, left_, right_); |
| 1129 if (!dst_.is(eax)) __ mov(dst_, eax); | 1129 if (!dst_.is(eax)) __ mov(dst_, eax); |
| 1130 __ bind(&done); | 1130 __ bind(&done); |
| 1131 } | 1131 } |
| 1132 | 1132 |
| 1133 | 1133 |
| 1134 static TypeInfo CalculateTypeInfo(TypeInfo operands_type, | 1134 static TypeInfo CalculateTypeInfo(TypeInfo operands_type, |
| 1135 Token::Value op, | 1135 Token::Value op, |
| 1136 const Result& right, | 1136 const Result& right, |
| 1137 const Result& left) { | 1137 const Result& left) { |
| 1138 // Set TypeInfo of result according to the operation performed. | 1138 // Set TypeInfo of result according to the operation performed. |
| 1139 // Rely on the fact that smis have a 31 bit payload on ia32. | 1139 // Rely on the fact that smis have a 31 bit payload on ia32. |
| 1140 ASSERT(kSmiValueSize == 31); | 1140 ASSERT(kSmiValueSize == 31); |
| 1141 switch (op) { | 1141 switch (op) { |
| 1142 case Token::COMMA: | 1142 case Token::COMMA: |
| 1143 return right.type_info(); | 1143 return right.type_info(); |
| 1144 case Token::OR: | 1144 case Token::OR: |
| 1145 case Token::AND: | 1145 case Token::AND: |
| 1146 // Result type can be either of the two input types. | 1146 // Result type can be either of the two input types. |
| 1147 return operands_type; | 1147 return operands_type; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1186 case Token::SHR: | 1186 case Token::SHR: |
| 1187 // Result is a smi if we shift by a constant >= 2, otherwise an integer32. | 1187 // Result is a smi if we shift by a constant >= 2, otherwise an integer32. |
| 1188 return (right.is_constant() && right.handle()->IsSmi() | 1188 return (right.is_constant() && right.handle()->IsSmi() |
| 1189 && Smi::cast(*right.handle())->value() >= 2) | 1189 && Smi::cast(*right.handle())->value() >= 2) |
| 1190 ? TypeInfo::Smi() | 1190 ? TypeInfo::Smi() |
| 1191 : TypeInfo::Integer32(); | 1191 : TypeInfo::Integer32(); |
| 1192 case Token::ADD: | 1192 case Token::ADD: |
| 1193 if (operands_type.IsSmi()) { | 1193 if (operands_type.IsSmi()) { |
| 1194 // The Integer32 range is big enough to take the sum of any two Smis. | 1194 // The Integer32 range is big enough to take the sum of any two Smis. |
| 1195 return TypeInfo::Integer32(); | 1195 return TypeInfo::Integer32(); |
| 1196 } else if (operands_type.IsNumber()) { |
| 1197 return TypeInfo::Number(); |
| 1198 } else if (left.type_info().IsString() || right.type_info().IsString()) { |
| 1199 return TypeInfo::String(); |
| 1196 } else { | 1200 } else { |
| 1197 // Result could be a string or a number. Check types of inputs. | 1201 return TypeInfo::Unknown(); |
| 1198 return operands_type.IsNumber() | |
| 1199 ? TypeInfo::Number() | |
| 1200 : TypeInfo::Unknown(); | |
| 1201 } | 1202 } |
| 1202 case Token::SHL: | 1203 case Token::SHL: |
| 1203 return TypeInfo::Integer32(); | 1204 return TypeInfo::Integer32(); |
| 1204 case Token::SUB: | 1205 case Token::SUB: |
| 1205 // The Integer32 range is big enough to take the difference of any two | 1206 // The Integer32 range is big enough to take the difference of any two |
| 1206 // Smis. | 1207 // Smis. |
| 1207 return (operands_type.IsSmi()) ? | 1208 return (operands_type.IsSmi()) ? |
| 1208 TypeInfo::Integer32() : | 1209 TypeInfo::Integer32() : |
| 1209 TypeInfo::Number(); | 1210 TypeInfo::Number(); |
| 1210 case Token::MUL: | 1211 case Token::MUL: |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1230 if (op == Token::COMMA) { | 1231 if (op == Token::COMMA) { |
| 1231 // Simply discard left value. | 1232 // Simply discard left value. |
| 1232 frame_->Nip(1); | 1233 frame_->Nip(1); |
| 1233 return; | 1234 return; |
| 1234 } | 1235 } |
| 1235 | 1236 |
| 1236 Result right = frame_->Pop(); | 1237 Result right = frame_->Pop(); |
| 1237 Result left = frame_->Pop(); | 1238 Result left = frame_->Pop(); |
| 1238 | 1239 |
| 1239 if (op == Token::ADD) { | 1240 if (op == Token::ADD) { |
| 1240 bool left_is_string = left.is_constant() && left.handle()->IsString(); | 1241 const bool left_is_string = left.type_info().IsString(); |
| 1241 bool right_is_string = right.is_constant() && right.handle()->IsString(); | 1242 const bool right_is_string = right.type_info().IsString(); |
| 1243 // Make sure constant strings have string type info. |
| 1244 ASSERT(!(left.is_constant() && left.handle()->IsString()) || |
| 1245 left_is_string); |
| 1246 ASSERT(!(right.is_constant() && right.handle()->IsString()) || |
| 1247 right_is_string); |
| 1242 if (left_is_string || right_is_string) { | 1248 if (left_is_string || right_is_string) { |
| 1243 frame_->Push(&left); | 1249 frame_->Push(&left); |
| 1244 frame_->Push(&right); | 1250 frame_->Push(&right); |
| 1245 Result answer; | 1251 Result answer; |
| 1246 if (left_is_string) { | 1252 if (left_is_string) { |
| 1247 if (right_is_string) { | 1253 if (right_is_string) { |
| 1248 // TODO(lrn): if both are constant strings | 1254 // TODO(lrn): if both are constant strings |
| 1249 // -- do a compile time cons, if allocation during codegen is allowed. | 1255 // -- do a compile time cons, if allocation during codegen is allowed. |
| 1250 answer = frame_->CallRuntime(Runtime::kStringAdd, 2); | 1256 StringAddStub stub(NO_STRING_CHECK_IN_STUB); |
| 1257 answer = frame_->CallStub(&stub, 2); |
| 1251 } else { | 1258 } else { |
| 1252 answer = | 1259 answer = |
| 1253 frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2); | 1260 frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2); |
| 1254 } | 1261 } |
| 1255 } else if (right_is_string) { | 1262 } else if (right_is_string) { |
| 1256 answer = | 1263 answer = |
| 1257 frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2); | 1264 frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2); |
| 1258 } | 1265 } |
| 1266 answer.set_type_info(TypeInfo::String()); |
| 1259 frame_->Push(&answer); | 1267 frame_->Push(&answer); |
| 1260 return; | 1268 return; |
| 1261 } | 1269 } |
| 1262 // Neither operand is known to be a string. | 1270 // Neither operand is known to be a string. |
| 1263 } | 1271 } |
| 1264 | 1272 |
| 1265 bool left_is_smi_constant = left.is_constant() && left.handle()->IsSmi(); | 1273 bool left_is_smi_constant = left.is_constant() && left.handle()->IsSmi(); |
| 1266 bool left_is_non_smi_constant = left.is_constant() && !left.handle()->IsSmi(); | 1274 bool left_is_non_smi_constant = left.is_constant() && !left.handle()->IsSmi(); |
| 1267 bool right_is_smi_constant = right.is_constant() && right.handle()->IsSmi(); | 1275 bool right_is_smi_constant = right.is_constant() && right.handle()->IsSmi(); |
| 1268 bool right_is_non_smi_constant = | 1276 bool right_is_non_smi_constant = |
| (...skipping 5727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6996 } | 7004 } |
| 6997 } | 7005 } |
| 6998 | 7006 |
| 6999 | 7007 |
| 7000 // The value in dst was optimistically incremented or decremented. The | 7008 // The value in dst was optimistically incremented or decremented. The |
| 7001 // result overflowed or was not smi tagged. Undo the operation, call | 7009 // result overflowed or was not smi tagged. Undo the operation, call |
| 7002 // into the runtime to convert the argument to a number, and call the | 7010 // into the runtime to convert the argument to a number, and call the |
| 7003 // specialized add or subtract stub. The result is left in dst. | 7011 // specialized add or subtract stub. The result is left in dst. |
| 7004 class DeferredPrefixCountOperation: public DeferredCode { | 7012 class DeferredPrefixCountOperation: public DeferredCode { |
| 7005 public: | 7013 public: |
| 7006 DeferredPrefixCountOperation(Register dst, bool is_increment) | 7014 DeferredPrefixCountOperation(Register dst, |
| 7007 : dst_(dst), is_increment_(is_increment) { | 7015 bool is_increment, |
| 7016 TypeInfo input_type) |
| 7017 : dst_(dst), is_increment_(is_increment), input_type_(input_type) { |
| 7008 set_comment("[ DeferredCountOperation"); | 7018 set_comment("[ DeferredCountOperation"); |
| 7009 } | 7019 } |
| 7010 | 7020 |
| 7011 virtual void Generate(); | 7021 virtual void Generate(); |
| 7012 | 7022 |
| 7013 private: | 7023 private: |
| 7014 Register dst_; | 7024 Register dst_; |
| 7015 bool is_increment_; | 7025 bool is_increment_; |
| 7026 TypeInfo input_type_; |
| 7016 }; | 7027 }; |
| 7017 | 7028 |
| 7018 | 7029 |
| 7019 void DeferredPrefixCountOperation::Generate() { | 7030 void DeferredPrefixCountOperation::Generate() { |
| 7020 // Undo the optimistic smi operation. | 7031 // Undo the optimistic smi operation. |
| 7021 if (is_increment_) { | 7032 if (is_increment_) { |
| 7022 __ sub(Operand(dst_), Immediate(Smi::FromInt(1))); | 7033 __ sub(Operand(dst_), Immediate(Smi::FromInt(1))); |
| 7023 } else { | 7034 } else { |
| 7024 __ add(Operand(dst_), Immediate(Smi::FromInt(1))); | 7035 __ add(Operand(dst_), Immediate(Smi::FromInt(1))); |
| 7025 } | 7036 } |
| 7026 __ push(dst_); | 7037 __ push(dst_); |
| 7027 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); | 7038 if (!input_type_.IsNumber()) { |
| 7028 __ push(eax); | 7039 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); |
| 7040 __ push(eax); |
| 7041 } |
| 7029 __ push(Immediate(Smi::FromInt(1))); | 7042 __ push(Immediate(Smi::FromInt(1))); |
| 7030 if (is_increment_) { | 7043 if (is_increment_) { |
| 7031 __ CallRuntime(Runtime::kNumberAdd, 2); | 7044 __ CallRuntime(Runtime::kNumberAdd, 2); |
| 7032 } else { | 7045 } else { |
| 7033 __ CallRuntime(Runtime::kNumberSub, 2); | 7046 __ CallRuntime(Runtime::kNumberSub, 2); |
| 7034 } | 7047 } |
| 7035 if (!dst_.is(eax)) __ mov(dst_, eax); | 7048 if (!dst_.is(eax)) __ mov(dst_, eax); |
| 7036 } | 7049 } |
| 7037 | 7050 |
| 7038 | 7051 |
| 7039 // The value in dst was optimistically incremented or decremented. The | 7052 // The value in dst was optimistically incremented or decremented. The |
| 7040 // result overflowed or was not smi tagged. Undo the operation and call | 7053 // result overflowed or was not smi tagged. Undo the operation and call |
| 7041 // into the runtime to convert the argument to a number. Update the | 7054 // into the runtime to convert the argument to a number. Update the |
| 7042 // original value in old. Call the specialized add or subtract stub. | 7055 // original value in old. Call the specialized add or subtract stub. |
| 7043 // The result is left in dst. | 7056 // The result is left in dst. |
| 7044 class DeferredPostfixCountOperation: public DeferredCode { | 7057 class DeferredPostfixCountOperation: public DeferredCode { |
| 7045 public: | 7058 public: |
| 7046 DeferredPostfixCountOperation(Register dst, Register old, bool is_increment) | 7059 DeferredPostfixCountOperation(Register dst, |
| 7047 : dst_(dst), old_(old), is_increment_(is_increment) { | 7060 Register old, |
| 7061 bool is_increment, |
| 7062 TypeInfo input_type) |
| 7063 : dst_(dst), |
| 7064 old_(old), |
| 7065 is_increment_(is_increment), |
| 7066 input_type_(input_type) { |
| 7048 set_comment("[ DeferredCountOperation"); | 7067 set_comment("[ DeferredCountOperation"); |
| 7049 } | 7068 } |
| 7050 | 7069 |
| 7051 virtual void Generate(); | 7070 virtual void Generate(); |
| 7052 | 7071 |
| 7053 private: | 7072 private: |
| 7054 Register dst_; | 7073 Register dst_; |
| 7055 Register old_; | 7074 Register old_; |
| 7056 bool is_increment_; | 7075 bool is_increment_; |
| 7076 TypeInfo input_type_; |
| 7057 }; | 7077 }; |
| 7058 | 7078 |
| 7059 | 7079 |
| 7060 void DeferredPostfixCountOperation::Generate() { | 7080 void DeferredPostfixCountOperation::Generate() { |
| 7061 // Undo the optimistic smi operation. | 7081 // Undo the optimistic smi operation. |
| 7062 if (is_increment_) { | 7082 if (is_increment_) { |
| 7063 __ sub(Operand(dst_), Immediate(Smi::FromInt(1))); | 7083 __ sub(Operand(dst_), Immediate(Smi::FromInt(1))); |
| 7064 } else { | 7084 } else { |
| 7065 __ add(Operand(dst_), Immediate(Smi::FromInt(1))); | 7085 __ add(Operand(dst_), Immediate(Smi::FromInt(1))); |
| 7066 } | 7086 } |
| 7067 __ push(dst_); | 7087 if (input_type_.IsNumber()) { |
| 7068 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); | 7088 __ push(dst_); // Save the input to use as the old value. |
| 7069 | 7089 __ push(dst_); |
| 7070 // Save the result of ToNumber to use as the old value. | 7090 } else { |
| 7071 __ push(eax); | 7091 __ push(dst_); |
| 7092 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); |
| 7093 __ push(eax); // Save the result of ToNumber to use as the old value. |
| 7094 __ push(eax); |
| 7095 } |
| 7072 | 7096 |
| 7073 // Call the runtime for the addition or subtraction. | 7097 // Call the runtime for the addition or subtraction. |
| 7074 __ push(eax); | |
| 7075 __ push(Immediate(Smi::FromInt(1))); | 7098 __ push(Immediate(Smi::FromInt(1))); |
| 7076 if (is_increment_) { | 7099 if (is_increment_) { |
| 7077 __ CallRuntime(Runtime::kNumberAdd, 2); | 7100 __ CallRuntime(Runtime::kNumberAdd, 2); |
| 7078 } else { | 7101 } else { |
| 7079 __ CallRuntime(Runtime::kNumberSub, 2); | 7102 __ CallRuntime(Runtime::kNumberSub, 2); |
| 7080 } | 7103 } |
| 7081 if (!dst_.is(eax)) __ mov(dst_, eax); | 7104 if (!dst_.is(eax)) __ mov(dst_, eax); |
| 7082 __ pop(old_); | 7105 __ pop(old_); |
| 7083 } | 7106 } |
| 7084 | 7107 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 7113 Result new_value = frame_->Pop(); | 7136 Result new_value = frame_->Pop(); |
| 7114 new_value.ToRegister(); | 7137 new_value.ToRegister(); |
| 7115 | 7138 |
| 7116 Result old_value; // Only allocated in the postfix case. | 7139 Result old_value; // Only allocated in the postfix case. |
| 7117 if (is_postfix) { | 7140 if (is_postfix) { |
| 7118 // Allocate a temporary to preserve the old value. | 7141 // Allocate a temporary to preserve the old value. |
| 7119 old_value = allocator_->Allocate(); | 7142 old_value = allocator_->Allocate(); |
| 7120 ASSERT(old_value.is_valid()); | 7143 ASSERT(old_value.is_valid()); |
| 7121 __ mov(old_value.reg(), new_value.reg()); | 7144 __ mov(old_value.reg(), new_value.reg()); |
| 7122 | 7145 |
| 7123 // The return value for postfix operations is the | 7146 // The return value for postfix operations is ToNumber(input). |
| 7124 // same as the input, and has the same number info. | 7147 // Keep more precise type info if the input is some kind of |
| 7125 old_value.set_type_info(new_value.type_info()); | 7148 // number already. If the input is not a number we have to wait |
| 7149 // for the deferred code to convert it. |
| 7150 if (new_value.type_info().IsNumber()) { |
| 7151 old_value.set_type_info(new_value.type_info()); |
| 7152 } |
| 7126 } | 7153 } |
| 7127 | 7154 |
| 7128 // Ensure the new value is writable. | 7155 // Ensure the new value is writable. |
| 7129 frame_->Spill(new_value.reg()); | 7156 frame_->Spill(new_value.reg()); |
| 7130 | 7157 |
| 7131 Result tmp; | 7158 Result tmp; |
| 7132 if (new_value.is_smi()) { | 7159 if (new_value.is_smi()) { |
| 7133 if (FLAG_debug_code) __ AbortIfNotSmi(new_value.reg()); | 7160 if (FLAG_debug_code) __ AbortIfNotSmi(new_value.reg()); |
| 7134 } else { | 7161 } else { |
| 7135 // We don't know statically if the input is a smi. | 7162 // We don't know statically if the input is a smi. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 7149 if (is_increment) { | 7176 if (is_increment) { |
| 7150 __ add(Operand(new_value.reg()), Immediate(Smi::FromInt(1))); | 7177 __ add(Operand(new_value.reg()), Immediate(Smi::FromInt(1))); |
| 7151 } else { | 7178 } else { |
| 7152 __ sub(Operand(new_value.reg()), Immediate(Smi::FromInt(1))); | 7179 __ sub(Operand(new_value.reg()), Immediate(Smi::FromInt(1))); |
| 7153 } | 7180 } |
| 7154 | 7181 |
| 7155 DeferredCode* deferred = NULL; | 7182 DeferredCode* deferred = NULL; |
| 7156 if (is_postfix) { | 7183 if (is_postfix) { |
| 7157 deferred = new DeferredPostfixCountOperation(new_value.reg(), | 7184 deferred = new DeferredPostfixCountOperation(new_value.reg(), |
| 7158 old_value.reg(), | 7185 old_value.reg(), |
| 7159 is_increment); | 7186 is_increment, |
| 7187 new_value.type_info()); |
| 7160 } else { | 7188 } else { |
| 7161 deferred = new DeferredPrefixCountOperation(new_value.reg(), | 7189 deferred = new DeferredPrefixCountOperation(new_value.reg(), |
| 7162 is_increment); | 7190 is_increment, |
| 7191 new_value.type_info()); |
| 7163 } | 7192 } |
| 7164 | 7193 |
| 7165 if (new_value.is_smi()) { | 7194 if (new_value.is_smi()) { |
| 7166 // In case we have a smi as input just check for overflow. | 7195 // In case we have a smi as input just check for overflow. |
| 7167 deferred->Branch(overflow); | 7196 deferred->Branch(overflow); |
| 7168 } else { | 7197 } else { |
| 7169 // If the count operation didn't overflow and the result is a valid | 7198 // If the count operation didn't overflow and the result is a valid |
| 7170 // smi, we're done. Otherwise, we jump to the deferred slow-case | 7199 // smi, we're done. Otherwise, we jump to the deferred slow-case |
| 7171 // code. | 7200 // code. |
| 7172 // We combine the overflow and the smi tag check if we could | 7201 // We combine the overflow and the smi tag check if we could |
| 7173 // successfully allocate a temporary byte register. | 7202 // successfully allocate a temporary byte register. |
| 7174 if (tmp.is_valid()) { | 7203 if (tmp.is_valid()) { |
| 7175 __ setcc(overflow, tmp.reg()); | 7204 __ setcc(overflow, tmp.reg()); |
| 7176 __ or_(Operand(tmp.reg()), new_value.reg()); | 7205 __ or_(Operand(tmp.reg()), new_value.reg()); |
| 7177 __ test(tmp.reg(), Immediate(kSmiTagMask)); | 7206 __ test(tmp.reg(), Immediate(kSmiTagMask)); |
| 7178 tmp.Unuse(); | 7207 tmp.Unuse(); |
| 7179 deferred->Branch(not_zero); | 7208 deferred->Branch(not_zero); |
| 7180 } else { | 7209 } else { |
| 7181 // Otherwise we test separately for overflow and smi tag. | 7210 // Otherwise we test separately for overflow and smi tag. |
| 7182 deferred->Branch(overflow); | 7211 deferred->Branch(overflow); |
| 7183 __ test(new_value.reg(), Immediate(kSmiTagMask)); | 7212 __ test(new_value.reg(), Immediate(kSmiTagMask)); |
| 7184 deferred->Branch(not_zero); | 7213 deferred->Branch(not_zero); |
| 7185 } | 7214 } |
| 7186 } | 7215 } |
| 7187 deferred->BindExit(); | 7216 deferred->BindExit(); |
| 7188 | 7217 |
| 7218 // Postfix count operations return their input converted to |
| 7219 // number. The case when the input is already a number is covered |
| 7220 // above in the allocation code for old_value. |
| 7221 if (is_postfix && !new_value.type_info().IsNumber()) { |
| 7222 old_value.set_type_info(TypeInfo::Number()); |
| 7223 } |
| 7224 |
| 7189 // The result of ++ or -- is an Integer32 if the | 7225 // The result of ++ or -- is an Integer32 if the |
| 7190 // input is a smi. Otherwise it is a number. | 7226 // input is a smi. Otherwise it is a number. |
| 7191 if (new_value.is_smi()) { | 7227 if (new_value.is_smi()) { |
| 7192 new_value.set_type_info(TypeInfo::Integer32()); | 7228 new_value.set_type_info(TypeInfo::Integer32()); |
| 7193 } else { | 7229 } else { |
| 7194 new_value.set_type_info(TypeInfo::Number()); | 7230 new_value.set_type_info(TypeInfo::Number()); |
| 7195 } | 7231 } |
| 7196 | 7232 |
| 7197 // Postfix: store the old value in the allocated slot under the | 7233 // Postfix: store the old value in the allocated slot under the |
| 7198 // reference. | 7234 // reference. |
| (...skipping 5365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12564 | 12600 |
| 12565 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12601 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 12566 // tagged as a small integer. | 12602 // tagged as a small integer. |
| 12567 __ bind(&runtime); | 12603 __ bind(&runtime); |
| 12568 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12604 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 12569 } | 12605 } |
| 12570 | 12606 |
| 12571 #undef __ | 12607 #undef __ |
| 12572 | 12608 |
| 12573 } } // namespace v8::internal | 12609 } } // namespace v8::internal |
| OLD | NEW |