| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.h" |
| 7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
| 8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
| 9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 value->ReplaceInput(0, node_); | 158 value->ReplaceInput(0, node_); |
| 159 return lowering_->Replace(value); | 159 return lowering_->Replace(value); |
| 160 } | 160 } |
| 161 return lowering_->Changed(node_); | 161 return lowering_->Changed(node_); |
| 162 } | 162 } |
| 163 | 163 |
| 164 Reduction ChangeToPureOperator(const Operator* op, Type* type) { | 164 Reduction ChangeToPureOperator(const Operator* op, Type* type) { |
| 165 return ChangeToPureOperator(op, false, type); | 165 return ChangeToPureOperator(op, false, type); |
| 166 } | 166 } |
| 167 | 167 |
| 168 bool IsStrong() { return is_strong(OpParameter<LanguageMode>(node_)); } |
| 169 |
| 168 bool OneInputIs(Type* t) { return left_type()->Is(t) || right_type()->Is(t); } | 170 bool OneInputIs(Type* t) { return left_type()->Is(t) || right_type()->Is(t); } |
| 169 | 171 |
| 170 bool BothInputsAre(Type* t) { | 172 bool BothInputsAre(Type* t) { |
| 171 return left_type()->Is(t) && right_type()->Is(t); | 173 return left_type()->Is(t) && right_type()->Is(t); |
| 172 } | 174 } |
| 173 | 175 |
| 174 bool OneInputCannotBe(Type* t) { | 176 bool OneInputCannotBe(Type* t) { |
| 175 return !left_type()->Maybe(t) || !right_type()->Maybe(t); | 177 return !left_type()->Maybe(t) || !right_type()->Maybe(t); |
| 176 } | 178 } |
| 177 | 179 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 } | 315 } |
| 314 }; | 316 }; |
| 315 | 317 |
| 316 | 318 |
| 317 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { | 319 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { |
| 318 JSBinopReduction r(this, node); | 320 JSBinopReduction r(this, node); |
| 319 if (r.BothInputsAre(Type::Number())) { | 321 if (r.BothInputsAre(Type::Number())) { |
| 320 // JSAdd(x:number, y:number) => NumberAdd(x, y) | 322 // JSAdd(x:number, y:number) => NumberAdd(x, y) |
| 321 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); | 323 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); |
| 322 } | 324 } |
| 323 if (r.NeitherInputCanBe(Type::StringOrReceiver())) { | 325 if (r.NeitherInputCanBe(Type::StringOrReceiver()) && !r.IsStrong()) { |
| 324 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) | 326 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) |
| 325 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 327 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 326 r.ConvertInputsToNumber(frame_state); | 328 r.ConvertInputsToNumber(frame_state); |
| 327 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); | 329 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); |
| 328 } | 330 } |
| 329 #if 0 | 331 #if 0 |
| 330 // TODO(turbofan): Lowering of StringAdd is disabled for now because: | 332 // TODO(turbofan): Lowering of StringAdd is disabled for now because: |
| 331 // a) The inserted ToString operation screws up valueOf vs. toString order. | 333 // a) The inserted ToString operation screws up valueOf vs. toString order. |
| 332 // b) Deoptimization at ToString doesn't have corresponding bailout id. | 334 // b) Deoptimization at ToString doesn't have corresponding bailout id. |
| 333 // c) Our current StringAddStub is actually non-pure and requires context. | 335 // c) Our current StringAddStub is actually non-pure and requires context. |
| 334 if (r.OneInputIs(Type::String())) { | 336 if ((r.OneInputIs(Type::String()) && !r.IsStrong()) || |
| 337 r.BothInputsAre(Type::String())) { |
| 335 // JSAdd(x:string, y:string) => StringAdd(x, y) | 338 // JSAdd(x:string, y:string) => StringAdd(x, y) |
| 336 // JSAdd(x:string, y) => StringAdd(x, ToString(y)) | 339 // JSAdd(x:string, y) => StringAdd(x, ToString(y)) |
| 337 // JSAdd(x, y:string) => StringAdd(ToString(x), y) | 340 // JSAdd(x, y:string) => StringAdd(ToString(x), y) |
| 338 r.ConvertInputsToString(); | 341 r.ConvertInputsToString(); |
| 339 return r.ChangeToPureOperator(simplified()->StringAdd()); | 342 return r.ChangeToPureOperator(simplified()->StringAdd()); |
| 340 } | 343 } |
| 341 #endif | 344 #endif |
| 342 return NoChange(); | 345 return NoChange(); |
| 343 } | 346 } |
| 344 | 347 |
| 345 | 348 |
| 346 Reduction JSTypedLowering::ReduceNumberBinop(Node* node, | 349 Reduction JSTypedLowering::ReduceNumberBinop(Node* node, |
| 347 const Operator* numberOp) { | 350 const Operator* numberOp) { |
| 348 JSBinopReduction r(this, node); | 351 JSBinopReduction r(this, node); |
| 349 if (is_strong(OpParameter<LanguageMode>(node))) { | 352 if (r.IsStrong()) { |
| 350 if (r.BothInputsAre(Type::Number())) { | 353 if (r.BothInputsAre(Type::Number())) { |
| 351 return r.ChangeToPureOperator(numberOp, Type::Number()); | 354 return r.ChangeToPureOperator(numberOp, Type::Number()); |
| 352 } | 355 } |
| 353 return NoChange(); | 356 return NoChange(); |
| 354 } | 357 } |
| 355 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 358 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 356 r.ConvertInputsToNumber(frame_state); | 359 r.ConvertInputsToNumber(frame_state); |
| 357 return r.ChangeToPureOperator(numberOp, Type::Number()); | 360 return r.ChangeToPureOperator(numberOp, Type::Number()); |
| 358 } | 361 } |
| 359 | 362 |
| 360 | 363 |
| 361 Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) { | 364 Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) { |
| 362 JSBinopReduction r(this, node); | 365 JSBinopReduction r(this, node); |
| 363 if (is_strong(OpParameter<LanguageMode>(node))) { | 366 if (r.IsStrong()) { |
| 364 if (r.BothInputsAre(Type::Number())) { | 367 if (r.BothInputsAre(Type::Number())) { |
| 365 r.ConvertInputsToUI32(kSigned, kSigned); | 368 r.ConvertInputsToUI32(kSigned, kSigned); |
| 366 return r.ChangeToPureOperator(intOp, Type::Integral32()); | 369 return r.ChangeToPureOperator(intOp, Type::Integral32()); |
| 367 } | 370 } |
| 368 return NoChange(); | 371 return NoChange(); |
| 369 } | 372 } |
| 370 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 373 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 371 r.ConvertInputsToNumber(frame_state); | 374 r.ConvertInputsToNumber(frame_state); |
| 372 r.ConvertInputsToUI32(kSigned, kSigned); | 375 r.ConvertInputsToUI32(kSigned, kSigned); |
| 373 return r.ChangeToPureOperator(intOp, Type::Integral32()); | 376 return r.ChangeToPureOperator(intOp, Type::Integral32()); |
| 374 } | 377 } |
| 375 | 378 |
| 376 | 379 |
| 377 Reduction JSTypedLowering::ReduceUI32Shift(Node* node, | 380 Reduction JSTypedLowering::ReduceUI32Shift(Node* node, |
| 378 Signedness left_signedness, | 381 Signedness left_signedness, |
| 379 const Operator* shift_op) { | 382 const Operator* shift_op) { |
| 380 JSBinopReduction r(this, node); | 383 JSBinopReduction r(this, node); |
| 381 Type* reduce_type = is_strong( | 384 Type* reduce_type = r.IsStrong() ? Type::Number() : Type::Primitive(); |
| 382 OpParameter<LanguageMode>(node)) ? Type::Number() : | |
| 383 Type::Primitive(); | |
| 384 if (r.BothInputsAre(reduce_type)) { | 385 if (r.BothInputsAre(reduce_type)) { |
| 385 r.ConvertInputsForShift(left_signedness); | 386 r.ConvertInputsForShift(left_signedness); |
| 386 return r.ChangeToPureOperator(shift_op, Type::Integral32()); | 387 return r.ChangeToPureOperator(shift_op, Type::Integral32()); |
| 387 } | 388 } |
| 388 return NoChange(); | 389 return NoChange(); |
| 389 } | 390 } |
| 390 | 391 |
| 391 | 392 |
| 392 Reduction JSTypedLowering::ReduceJSComparison(Node* node) { | 393 Reduction JSTypedLowering::ReduceJSComparison(Node* node) { |
| 393 JSBinopReduction r(this, node); | 394 JSBinopReduction r(this, node); |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1177 } | 1178 } |
| 1178 | 1179 |
| 1179 | 1180 |
| 1180 MachineOperatorBuilder* JSTypedLowering::machine() const { | 1181 MachineOperatorBuilder* JSTypedLowering::machine() const { |
| 1181 return jsgraph()->machine(); | 1182 return jsgraph()->machine(); |
| 1182 } | 1183 } |
| 1183 | 1184 |
| 1184 } // namespace compiler | 1185 } // namespace compiler |
| 1185 } // namespace internal | 1186 } // namespace internal |
| 1186 } // namespace v8 | 1187 } // namespace v8 |
| OLD | NEW |