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 "test/unittests/compiler/instruction-selector-unittest.h" | 5 #include "test/unittests/compiler/instruction-selector-unittest.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace compiler { | 9 namespace compiler { |
10 | 10 |
(...skipping 3224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3235 EXPECT_EQ(3U, s[0]->InputCount()); | 3235 EXPECT_EQ(3U, s[0]->InputCount()); |
3236 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); | 3236 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); |
3237 EXPECT_EQ(1U, s[0]->OutputCount()); | 3237 EXPECT_EQ(1U, s[0]->OutputCount()); |
3238 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 3238 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
3239 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); | 3239 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
3240 } | 3240 } |
3241 } | 3241 } |
3242 } | 3242 } |
3243 } | 3243 } |
3244 | 3244 |
| 3245 // ----------------------------------------------------------------------------- |
| 3246 // Flag-setting add and and instructions. |
| 3247 |
| 3248 const IntegerCmp kBinopCmpZeroRightInstructions[] = { |
| 3249 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, |
| 3250 MachineType::Int32()}, |
| 3251 kEqual, |
| 3252 kEqual}, |
| 3253 {{&RawMachineAssembler::Word32NotEqual, "Word32NotEqual", kArm64Cmp32, |
| 3254 MachineType::Int32()}, |
| 3255 kNotEqual, |
| 3256 kNotEqual}, |
| 3257 {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kArm64Cmp32, |
| 3258 MachineType::Int32()}, |
| 3259 kNegative, |
| 3260 kNegative}, |
| 3261 {{&RawMachineAssembler::Int32GreaterThanOrEqual, "Int32GreaterThanOrEqual", |
| 3262 kArm64Cmp32, MachineType::Int32()}, |
| 3263 kPositiveOrZero, |
| 3264 kPositiveOrZero}, |
| 3265 {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual", |
| 3266 kArm64Cmp32, MachineType::Int32()}, |
| 3267 kEqual, |
| 3268 kEqual}, |
| 3269 {{&RawMachineAssembler::Uint32GreaterThan, "Uint32GreaterThan", kArm64Cmp32, |
| 3270 MachineType::Int32()}, |
| 3271 kNotEqual, |
| 3272 kNotEqual}}; |
| 3273 |
| 3274 const IntegerCmp kBinopCmpZeroLeftInstructions[] = { |
| 3275 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, |
| 3276 MachineType::Int32()}, |
| 3277 kEqual, |
| 3278 kEqual}, |
| 3279 {{&RawMachineAssembler::Word32NotEqual, "Word32NotEqual", kArm64Cmp32, |
| 3280 MachineType::Int32()}, |
| 3281 kNotEqual, |
| 3282 kNotEqual}, |
| 3283 {{&RawMachineAssembler::Int32GreaterThan, "Int32GreaterThan", kArm64Cmp32, |
| 3284 MachineType::Int32()}, |
| 3285 kNegative, |
| 3286 kNegative}, |
| 3287 {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual", |
| 3288 kArm64Cmp32, MachineType::Int32()}, |
| 3289 kPositiveOrZero, |
| 3290 kPositiveOrZero}, |
| 3291 {{&RawMachineAssembler::Uint32GreaterThanOrEqual, |
| 3292 "Uint32GreaterThanOrEqual", kArm64Cmp32, MachineType::Int32()}, |
| 3293 kEqual, |
| 3294 kEqual}, |
| 3295 {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kArm64Cmp32, |
| 3296 MachineType::Int32()}, |
| 3297 kNotEqual, |
| 3298 kNotEqual}}; |
| 3299 |
| 3300 struct FlagSettingInst { |
| 3301 MachInst2 mi; |
| 3302 ArchOpcode no_output_opcode; |
| 3303 }; |
| 3304 |
| 3305 std::ostream& operator<<(std::ostream& os, const FlagSettingInst& inst) { |
| 3306 return os << inst.mi.constructor_name; |
| 3307 } |
| 3308 |
| 3309 const FlagSettingInst kFlagSettingInstructions[] = { |
| 3310 {{&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, |
| 3311 MachineType::Int32()}, |
| 3312 kArm64Cmn32}, |
| 3313 {{&RawMachineAssembler::Word32And, "Word32And", kArm64And32, |
| 3314 MachineType::Int32()}, |
| 3315 kArm64Tst32}}; |
| 3316 |
| 3317 typedef InstructionSelectorTestWithParam<FlagSettingInst> |
| 3318 InstructionSelectorFlagSettingTest; |
| 3319 |
| 3320 TEST_P(InstructionSelectorFlagSettingTest, CmpZeroRight) { |
| 3321 const FlagSettingInst inst = GetParam(); |
| 3322 // Add with single user : a cmp instruction. |
| 3323 TRACED_FOREACH(IntegerCmp, cmp, kBinopCmpZeroRightInstructions) { |
| 3324 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3325 MachineType::Int32()); |
| 3326 RawMachineLabel a, b; |
| 3327 Node* binop = (m.*inst.mi.constructor)(m.Parameter(0), m.Parameter(1)); |
| 3328 Node* comp = (m.*cmp.mi.constructor)(binop, m.Int32Constant(0)); |
| 3329 m.Branch(comp, &a, &b); |
| 3330 m.Bind(&a); |
| 3331 m.Return(m.Int32Constant(1)); |
| 3332 m.Bind(&b); |
| 3333 m.Return(m.Int32Constant(0)); |
| 3334 Stream s = m.Build(); |
| 3335 ASSERT_EQ(1U, s.size()); |
| 3336 ASSERT_EQ(4U, s[0]->InputCount()); // The labels are also inputs. |
| 3337 EXPECT_EQ(inst.no_output_opcode, s[0]->arch_opcode()); |
| 3338 EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0))); |
| 3339 EXPECT_EQ(s.ToVreg(m.Parameter(1)), s.ToVreg(s[0]->InputAt(1))); |
| 3340 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 3341 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 3342 } |
| 3343 } |
| 3344 |
| 3345 TEST_P(InstructionSelectorFlagSettingTest, CmpZeroLeft) { |
| 3346 const FlagSettingInst inst = GetParam(); |
| 3347 // Test a cmp with zero on the left-hand side. |
| 3348 TRACED_FOREACH(IntegerCmp, cmp, kBinopCmpZeroLeftInstructions) { |
| 3349 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3350 MachineType::Int32()); |
| 3351 RawMachineLabel a, b; |
| 3352 Node* binop = (m.*inst.mi.constructor)(m.Parameter(0), m.Parameter(1)); |
| 3353 Node* comp = (m.*cmp.mi.constructor)(m.Int32Constant(0), binop); |
| 3354 m.Branch(comp, &a, &b); |
| 3355 m.Bind(&a); |
| 3356 m.Return(m.Int32Constant(1)); |
| 3357 m.Bind(&b); |
| 3358 m.Return(m.Int32Constant(0)); |
| 3359 Stream s = m.Build(); |
| 3360 ASSERT_EQ(1U, s.size()); |
| 3361 ASSERT_EQ(4U, s[0]->InputCount()); // The labels are also inputs. |
| 3362 EXPECT_EQ(inst.no_output_opcode, s[0]->arch_opcode()); |
| 3363 EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0))); |
| 3364 EXPECT_EQ(s.ToVreg(m.Parameter(1)), s.ToVreg(s[0]->InputAt(1))); |
| 3365 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 3366 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 3367 } |
| 3368 } |
| 3369 |
| 3370 TEST_P(InstructionSelectorFlagSettingTest, CmpZeroOnlyUserInBasicBlock) { |
| 3371 const FlagSettingInst inst = GetParam(); |
| 3372 // Binop with additional users, but in a different basic block. |
| 3373 TRACED_FOREACH(IntegerCmp, cmp, kBinopCmpZeroRightInstructions) { |
| 3374 // For kEqual and kNotEqual, we generate a cbz or cbnz. |
| 3375 if (cmp.cond == kEqual || cmp.cond == kNotEqual) continue; |
| 3376 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3377 MachineType::Int32()); |
| 3378 RawMachineLabel a, b; |
| 3379 Node* binop = (m.*inst.mi.constructor)(m.Parameter(0), m.Parameter(1)); |
| 3380 Node* comp = (m.*cmp.mi.constructor)(binop, m.Int32Constant(0)); |
| 3381 m.Branch(comp, &a, &b); |
| 3382 m.Bind(&a); |
| 3383 m.Return(binop); |
| 3384 m.Bind(&b); |
| 3385 m.Return(m.Int32Constant(0)); |
| 3386 Stream s = m.Build(); |
| 3387 ASSERT_EQ(1U, s.size()); |
| 3388 ASSERT_EQ(4U, s[0]->InputCount()); // The labels are also inputs. |
| 3389 EXPECT_EQ(inst.mi.arch_opcode, s[0]->arch_opcode()); |
| 3390 EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0))); |
| 3391 EXPECT_EQ(s.ToVreg(m.Parameter(1)), s.ToVreg(s[0]->InputAt(1))); |
| 3392 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 3393 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 3394 } |
| 3395 } |
| 3396 |
| 3397 TEST_P(InstructionSelectorFlagSettingTest, ShiftedOperand) { |
| 3398 const FlagSettingInst inst = GetParam(); |
| 3399 // Like the test above, but with a shifted input to the binary operator. |
| 3400 TRACED_FOREACH(IntegerCmp, cmp, kBinopCmpZeroRightInstructions) { |
| 3401 // For kEqual and kNotEqual, we generate a cbz or cbnz. |
| 3402 if (cmp.cond == kEqual || cmp.cond == kNotEqual) continue; |
| 3403 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3404 MachineType::Int32()); |
| 3405 RawMachineLabel a, b; |
| 3406 Node* imm = m.Int32Constant(5); |
| 3407 Node* shift = m.Word32Shl(m.Parameter(1), imm); |
| 3408 Node* binop = (m.*inst.mi.constructor)(m.Parameter(0), shift); |
| 3409 Node* comp = (m.*cmp.mi.constructor)(binop, m.Int32Constant(0)); |
| 3410 m.Branch(comp, &a, &b); |
| 3411 m.Bind(&a); |
| 3412 m.Return(binop); |
| 3413 m.Bind(&b); |
| 3414 m.Return(m.Int32Constant(0)); |
| 3415 Stream s = m.Build(); |
| 3416 ASSERT_EQ(1U, s.size()); |
| 3417 ASSERT_EQ(5U, s[0]->InputCount()); // The labels are also inputs. |
| 3418 EXPECT_EQ(inst.mi.arch_opcode, s[0]->arch_opcode()); |
| 3419 EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0))); |
| 3420 EXPECT_EQ(s.ToVreg(m.Parameter(1)), s.ToVreg(s[0]->InputAt(1))); |
| 3421 EXPECT_EQ(5, s.ToInt32(s[0]->InputAt(2))); |
| 3422 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); |
| 3423 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 3424 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 3425 } |
| 3426 } |
| 3427 |
| 3428 TEST_P(InstructionSelectorFlagSettingTest, UsersInSameBasicBlock) { |
| 3429 const FlagSettingInst inst = GetParam(); |
| 3430 // Binop with additional users, in the same basic block. We need to make sure |
| 3431 // we don't try to optimise this case. |
| 3432 TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) { |
| 3433 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3434 MachineType::Int32()); |
| 3435 RawMachineLabel a, b; |
| 3436 Node* binop = (m.*inst.mi.constructor)(m.Parameter(0), m.Parameter(1)); |
| 3437 Node* mul = m.Int32Mul(m.Parameter(0), binop); |
| 3438 Node* comp = (m.*cmp.mi.constructor)(binop, m.Int32Constant(0)); |
| 3439 m.Branch(comp, &a, &b); |
| 3440 m.Bind(&a); |
| 3441 m.Return(mul); |
| 3442 m.Bind(&b); |
| 3443 m.Return(m.Int32Constant(0)); |
| 3444 Stream s = m.Build(); |
| 3445 ASSERT_EQ(3U, s.size()); |
| 3446 EXPECT_EQ(inst.mi.arch_opcode, s[0]->arch_opcode()); |
| 3447 EXPECT_NE(kFlags_branch, s[0]->flags_mode()); |
| 3448 EXPECT_EQ(kArm64Mul32, s[1]->arch_opcode()); |
| 3449 EXPECT_EQ(cmp.cond == kEqual ? kArm64CompareAndBranch32 : kArm64Cmp32, |
| 3450 s[2]->arch_opcode()); |
| 3451 EXPECT_EQ(kFlags_branch, s[2]->flags_mode()); |
| 3452 EXPECT_EQ(cmp.cond, s[2]->flags_condition()); |
| 3453 } |
| 3454 } |
| 3455 |
| 3456 TEST_P(InstructionSelectorFlagSettingTest, CommuteImmediate) { |
| 3457 const FlagSettingInst inst = GetParam(); |
| 3458 // Immediate on left hand side of the binary operator. |
| 3459 TRACED_FOREACH(IntegerCmp, cmp, kBinopCmpZeroRightInstructions) { |
| 3460 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3461 RawMachineLabel a, b; |
| 3462 // 3 can be an immediate on both arithmetic and logical instructions. |
| 3463 Node* imm = m.Int32Constant(3); |
| 3464 Node* binop = (m.*inst.mi.constructor)(imm, m.Parameter(0)); |
| 3465 Node* comp = (m.*cmp.mi.constructor)(binop, m.Int32Constant(0)); |
| 3466 m.Branch(comp, &a, &b); |
| 3467 m.Bind(&a); |
| 3468 m.Return(m.Int32Constant(1)); |
| 3469 m.Bind(&b); |
| 3470 m.Return(m.Int32Constant(0)); |
| 3471 Stream s = m.Build(); |
| 3472 ASSERT_EQ(1U, s.size()); |
| 3473 ASSERT_EQ(4U, s[0]->InputCount()); // The labels are also inputs. |
| 3474 EXPECT_EQ(inst.no_output_opcode, s[0]->arch_opcode()); |
| 3475 EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0))); |
| 3476 EXPECT_EQ(3, s.ToInt32(s[0]->InputAt(1))); |
| 3477 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 3478 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 3479 } |
| 3480 } |
| 3481 |
| 3482 TEST_P(InstructionSelectorFlagSettingTest, CommuteShift) { |
| 3483 const FlagSettingInst inst = GetParam(); |
| 3484 // Left-hand side operand shifted by immediate. |
| 3485 TRACED_FOREACH(IntegerCmp, cmp, kBinopCmpZeroRightInstructions) { |
| 3486 TRACED_FOREACH(Shift, shift, kShiftInstructions) { |
| 3487 // Only test relevant shifted operands. |
| 3488 if (shift.mi.machine_type != MachineType::Int32()) continue; |
| 3489 |
| 3490 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3491 MachineType::Int32()); |
| 3492 Node* imm = m.Int32Constant(5); |
| 3493 Node* shifted_operand = (m.*shift.mi.constructor)(m.Parameter(0), imm); |
| 3494 Node* binop = (m.*inst.mi.constructor)(shifted_operand, m.Parameter(1)); |
| 3495 Node* comp = (m.*cmp.mi.constructor)(binop, m.Int32Constant(0)); |
| 3496 m.Return(comp); |
| 3497 Stream s = m.Build(); |
| 3498 // Cmn does not support ROR shifts. |
| 3499 if (inst.no_output_opcode == kArm64Cmn32 && |
| 3500 shift.mi.arch_opcode == kArm64Ror32) { |
| 3501 ASSERT_EQ(2U, s.size()); |
| 3502 continue; |
| 3503 } |
| 3504 ASSERT_EQ(1U, s.size()); |
| 3505 EXPECT_EQ(inst.no_output_opcode, s[0]->arch_opcode()); |
| 3506 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); |
| 3507 EXPECT_EQ(3U, s[0]->InputCount()); |
| 3508 EXPECT_EQ(5, s.ToInt64(s[0]->InputAt(2))); |
| 3509 EXPECT_EQ(1U, s[0]->OutputCount()); |
| 3510 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 3511 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 3512 } |
| 3513 } |
| 3514 } |
| 3515 |
| 3516 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
| 3517 InstructionSelectorFlagSettingTest, |
| 3518 ::testing::ValuesIn(kFlagSettingInstructions)); |
| 3519 |
| 3520 TEST_F(InstructionSelectorTest, TstInvalidImmediate) { |
| 3521 // Make sure we do not generate an invalid immediate for TST. |
| 3522 TRACED_FOREACH(IntegerCmp, cmp, kBinopCmpZeroRightInstructions) { |
| 3523 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 3524 RawMachineLabel a, b; |
| 3525 // 5 is not a valid constant for TST. |
| 3526 Node* imm = m.Int32Constant(5); |
| 3527 Node* binop = m.Word32And(imm, m.Parameter(0)); |
| 3528 Node* comp = (m.*cmp.mi.constructor)(binop, m.Int32Constant(0)); |
| 3529 m.Branch(comp, &a, &b); |
| 3530 m.Bind(&a); |
| 3531 m.Return(m.Int32Constant(1)); |
| 3532 m.Bind(&b); |
| 3533 m.Return(m.Int32Constant(0)); |
| 3534 Stream s = m.Build(); |
| 3535 ASSERT_EQ(1U, s.size()); |
| 3536 ASSERT_EQ(4U, s[0]->InputCount()); // The labels are also inputs. |
| 3537 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); |
| 3538 EXPECT_NE(InstructionOperand::IMMEDIATE, s[0]->InputAt(0)->kind()); |
| 3539 EXPECT_NE(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 3540 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
| 3541 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 3542 } |
| 3543 } |
| 3544 |
| 3545 TEST_F(InstructionSelectorTest, CommuteAddsExtend) { |
| 3546 // Extended left-hand side operand. |
| 3547 TRACED_FOREACH(IntegerCmp, cmp, kBinopCmpZeroRightInstructions) { |
| 3548 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 3549 MachineType::Int32()); |
| 3550 Node* extend = m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)), |
| 3551 m.Int32Constant(24)); |
| 3552 Node* binop = m.Int32Add(extend, m.Parameter(1)); |
| 3553 m.Return((m.*cmp.mi.constructor)(binop, m.Int32Constant(0))); |
| 3554 Stream s = m.Build(); |
| 3555 ASSERT_EQ(1U, s.size()); |
| 3556 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); |
| 3557 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
| 3558 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); |
| 3559 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); |
| 3560 } |
| 3561 } |
3245 | 3562 |
3246 // ----------------------------------------------------------------------------- | 3563 // ----------------------------------------------------------------------------- |
3247 // Miscellaneous | 3564 // Miscellaneous |
3248 | 3565 |
3249 | 3566 |
3250 static const MachInst2 kLogicalWithNotRHSs[] = { | 3567 static const MachInst2 kLogicalWithNotRHSs[] = { |
3251 {&RawMachineAssembler::Word32And, "Word32And", kArm64Bic32, | 3568 {&RawMachineAssembler::Word32And, "Word32And", kArm64Bic32, |
3252 MachineType::Int32()}, | 3569 MachineType::Int32()}, |
3253 {&RawMachineAssembler::Word64And, "Word64And", kArm64Bic, | 3570 {&RawMachineAssembler::Word64And, "Word64And", kArm64Bic, |
3254 MachineType::Int64()}, | 3571 MachineType::Int64()}, |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3935 EXPECT_EQ(kArm64Float64Neg, s[0]->arch_opcode()); | 4252 EXPECT_EQ(kArm64Float64Neg, s[0]->arch_opcode()); |
3936 ASSERT_EQ(1U, s[0]->InputCount()); | 4253 ASSERT_EQ(1U, s[0]->InputCount()); |
3937 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 4254 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
3938 ASSERT_EQ(1U, s[0]->OutputCount()); | 4255 ASSERT_EQ(1U, s[0]->OutputCount()); |
3939 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 4256 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
3940 } | 4257 } |
3941 | 4258 |
3942 } // namespace compiler | 4259 } // namespace compiler |
3943 } // namespace internal | 4260 } // namespace internal |
3944 } // namespace v8 | 4261 } // namespace v8 |
OLD | NEW |