| 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/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
| 7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
| 8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| 11 #include "src/compiler/node-matchers.h" | 11 #include "src/compiler/node-matchers.h" |
| 12 #include "src/compiler/node-properties.h" | 12 #include "src/compiler/node-properties.h" |
| 13 #include "src/compiler/operator-properties.h" | 13 #include "src/compiler/operator-properties.h" |
| 14 #include "src/type-cache.h" | 14 #include "src/type-cache.h" |
| 15 #include "src/types.h" | 15 #include "src/types.h" |
| 16 | 16 |
| 17 namespace v8 { | 17 namespace v8 { |
| 18 namespace internal { | 18 namespace internal { |
| 19 namespace compiler { | 19 namespace compiler { |
| 20 | 20 |
| 21 // A helper class to simplify the process of reducing a single binop node with a | 21 // A helper class to simplify the process of reducing a single binop node with a |
| 22 // JSOperator. This class manages the rewriting of context, control, and effect | 22 // JSOperator. This class manages the rewriting of context, control, and effect |
| 23 // dependencies during lowering of a binop and contains numerous helper | 23 // dependencies during lowering of a binop and contains numerous helper |
| 24 // functions for matching the types of inputs to an operation. | 24 // functions for matching the types of inputs to an operation. |
| 25 class JSBinopReduction final { | 25 class JSBinopReduction final { |
| 26 public: | 26 public: |
| 27 JSBinopReduction(JSTypedLowering* lowering, Node* node) | 27 JSBinopReduction(JSTypedLowering* lowering, Node* node) |
| 28 : lowering_(lowering), node_(node) {} | 28 : lowering_(lowering), node_(node) {} |
| 29 | 29 |
| 30 void ConvertInputsToNumber(Node* frame_state) { | 30 void ConvertInputsToNumberOrUndefined(Node* frame_state) { |
| 31 // To convert the inputs to numbers, we have to provide frame states | 31 // To convert the inputs to numbers, we have to provide frame states |
| 32 // for lazy bailouts in the ToNumber conversions. | 32 // for lazy bailouts in the ToNumber conversions. |
| 33 // We use a little hack here: we take the frame state before the binary | 33 // We use a little hack here: we take the frame state before the binary |
| 34 // operation and use it to construct the frame states for the conversion | 34 // operation and use it to construct the frame states for the conversion |
| 35 // so that after the deoptimization, the binary operation IC gets | 35 // so that after the deoptimization, the binary operation IC gets |
| 36 // already converted values from full code. This way we are sure that we | 36 // already converted values from full code. This way we are sure that we |
| 37 // will not re-do any of the side effects. | 37 // will not re-do any of the side effects. |
| 38 | 38 |
| 39 Node* left_input = nullptr; | 39 Node* left_input = nullptr; |
| 40 Node* right_input = nullptr; | 40 Node* right_input = nullptr; |
| 41 bool left_is_primitive = left_type()->Is(Type::PlainPrimitive()); | 41 bool left_is_primitive = left_type()->Is(Type::PlainPrimitive()); |
| 42 bool right_is_primitive = right_type()->Is(Type::PlainPrimitive()); | 42 bool right_is_primitive = right_type()->Is(Type::PlainPrimitive()); |
| 43 bool handles_exception = NodeProperties::IsExceptionalCall(node_); | 43 bool handles_exception = NodeProperties::IsExceptionalCall(node_); |
| 44 | 44 |
| 45 if (!left_is_primitive && !right_is_primitive && handles_exception) { | 45 if (!left_is_primitive && !right_is_primitive && handles_exception) { |
| 46 ConvertBothInputsToNumber(&left_input, &right_input, frame_state); | 46 ConvertBothInputsToNumber(&left_input, &right_input, frame_state); |
| 47 } else { | 47 } else { |
| 48 left_input = left_is_primitive | 48 left_input = left_is_primitive |
| 49 ? ConvertPlainPrimitiveToNumber(left()) | 49 ? ConvertPlainPrimitiveToNumberOrUndefined(left()) |
| 50 : ConvertSingleInputToNumber( | 50 : ConvertSingleInputToNumber( |
| 51 left(), CreateFrameStateForLeftInput(frame_state)); | 51 left(), CreateFrameStateForLeftInput(frame_state)); |
| 52 right_input = right_is_primitive | 52 right_input = right_is_primitive |
| 53 ? ConvertPlainPrimitiveToNumber(right()) | 53 ? ConvertPlainPrimitiveToNumberOrUndefined(right()) |
| 54 : ConvertSingleInputToNumber( | 54 : ConvertSingleInputToNumber( |
| 55 right(), CreateFrameStateForRightInput( | 55 right(), CreateFrameStateForRightInput( |
| 56 frame_state, left_input)); | 56 frame_state, left_input)); |
| 57 } | 57 } |
| 58 | 58 |
| 59 node_->ReplaceInput(0, left_input); | 59 node_->ReplaceInput(0, left_input); |
| 60 node_->ReplaceInput(1, right_input); | 60 node_->ReplaceInput(1, right_input); |
| 61 } | 61 } |
| 62 | 62 |
| 63 void ConvertInputsToUI32(Signedness left_signedness, | 63 void ConvertInputsToUI32(Signedness left_signedness, |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 graph()->NewNode(stack->op(), stack->InputCount(), &new_values.front()); | 235 graph()->NewNode(stack->op(), stack->InputCount(), &new_values.front()); |
| 236 | 236 |
| 237 return graph()->NewNode( | 237 return graph()->NewNode( |
| 238 op, frame_state->InputAt(kFrameStateParametersInput), | 238 op, frame_state->InputAt(kFrameStateParametersInput), |
| 239 frame_state->InputAt(kFrameStateLocalsInput), new_stack, | 239 frame_state->InputAt(kFrameStateLocalsInput), new_stack, |
| 240 frame_state->InputAt(kFrameStateContextInput), | 240 frame_state->InputAt(kFrameStateContextInput), |
| 241 frame_state->InputAt(kFrameStateFunctionInput), | 241 frame_state->InputAt(kFrameStateFunctionInput), |
| 242 frame_state->InputAt(kFrameStateOuterStateInput)); | 242 frame_state->InputAt(kFrameStateOuterStateInput)); |
| 243 } | 243 } |
| 244 | 244 |
| 245 Node* ConvertPlainPrimitiveToNumber(Node* node) { | 245 Node* ConvertPlainPrimitiveToNumberOrUndefined(Node* node) { |
| 246 DCHECK(NodeProperties::GetType(node)->Is(Type::PlainPrimitive())); | 246 DCHECK(NodeProperties::GetType(node)->Is(Type::PlainPrimitive())); |
| 247 if (NodeProperties::GetType(node)->Is(Type::NumberOrUndefined())) { |
| 248 return node; |
| 249 } |
| 247 // Avoid inserting too many eager ToNumber() operations. | 250 // Avoid inserting too many eager ToNumber() operations. |
| 248 Reduction const reduction = lowering_->ReduceJSToNumberInput(node); | 251 Reduction const reduction = lowering_->ReduceJSToNumberInput(node); |
| 249 if (reduction.Changed()) return reduction.replacement(); | 252 if (reduction.Changed()) return reduction.replacement(); |
| 250 // TODO(jarin) Use PlainPrimitiveToNumber once we have it. | 253 // TODO(jarin) Use PlainPrimitiveToNumber once we have it. |
| 251 return graph()->NewNode( | 254 return graph()->NewNode( |
| 252 javascript()->ToNumber(), node, jsgraph()->NoContextConstant(), | 255 javascript()->ToNumber(), node, jsgraph()->NoContextConstant(), |
| 253 jsgraph()->EmptyFrameState(), graph()->start(), graph()->start()); | 256 jsgraph()->EmptyFrameState(), graph()->start(), graph()->start()); |
| 254 } | 257 } |
| 255 | 258 |
| 256 Node* ConvertSingleInputToNumber(Node* node, Node* frame_state) { | 259 Node* ConvertSingleInputToNumber(Node* node, Node* frame_state) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 double max = kMaxInt / (1 << k); | 357 double max = kMaxInt / (1 << k); |
| 355 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); | 358 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); |
| 356 } | 359 } |
| 357 } | 360 } |
| 358 | 361 |
| 359 | 362 |
| 360 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { | 363 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { |
| 361 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 364 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 362 | 365 |
| 363 JSBinopReduction r(this, node); | 366 JSBinopReduction r(this, node); |
| 364 if (r.BothInputsAre(Type::Number())) { | 367 if (r.BothInputsAre(Type::NumberOrUndefined())) { |
| 365 // JSAdd(x:number, y:number) => NumberAdd(x, y) | 368 // JSAdd(x:number, y:number) => NumberAdd(x, y) |
| 366 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); | 369 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); |
| 367 } | 370 } |
| 368 if (r.NeitherInputCanBe(Type::StringOrReceiver())) { | 371 if (r.NeitherInputCanBe(Type::StringOrReceiver())) { |
| 369 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) | 372 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) |
| 370 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 373 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 371 r.ConvertInputsToNumber(frame_state); | 374 r.ConvertInputsToNumberOrUndefined(frame_state); |
| 372 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); | 375 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); |
| 373 } | 376 } |
| 374 if (r.BothInputsAre(Type::String())) { | 377 if (r.BothInputsAre(Type::String())) { |
| 375 // JSAdd(x:string, y:string) => CallStub[StringAdd](x, y) | 378 // JSAdd(x:string, y:string) => CallStub[StringAdd](x, y) |
| 376 Callable const callable = | 379 Callable const callable = |
| 377 CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); | 380 CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); |
| 378 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( | 381 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
| 379 isolate(), graph()->zone(), callable.descriptor(), 0, | 382 isolate(), graph()->zone(), callable.descriptor(), 0, |
| 380 CallDescriptor::kNeedsFrameState, node->op()->properties()); | 383 CallDescriptor::kNeedsFrameState, node->op()->properties()); |
| 381 DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op())); | 384 DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op())); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 401 return NoChange(); | 404 return NoChange(); |
| 402 } | 405 } |
| 403 | 406 |
| 404 | 407 |
| 405 Reduction JSTypedLowering::ReduceNumberBinop(Node* node, | 408 Reduction JSTypedLowering::ReduceNumberBinop(Node* node, |
| 406 const Operator* numberOp) { | 409 const Operator* numberOp) { |
| 407 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 410 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 408 | 411 |
| 409 JSBinopReduction r(this, node); | 412 JSBinopReduction r(this, node); |
| 410 if (numberOp == simplified()->NumberModulus()) { | 413 if (numberOp == simplified()->NumberModulus()) { |
| 411 if (r.BothInputsAre(Type::Number())) { | 414 if (r.BothInputsAre(Type::NumberOrUndefined())) { |
| 412 return r.ChangeToPureOperator(numberOp, Type::Number()); | 415 return r.ChangeToPureOperator(numberOp, Type::Number()); |
| 413 } | 416 } |
| 414 return NoChange(); | 417 return NoChange(); |
| 415 } | 418 } |
| 416 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 419 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 417 r.ConvertInputsToNumber(frame_state); | 420 r.ConvertInputsToNumberOrUndefined(frame_state); |
| 418 return r.ChangeToPureOperator(numberOp, Type::Number()); | 421 return r.ChangeToPureOperator(numberOp, Type::Number()); |
| 419 } | 422 } |
| 420 | 423 |
| 421 | 424 |
| 422 Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) { | 425 Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) { |
| 423 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 426 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 424 | 427 |
| 425 JSBinopReduction r(this, node); | 428 JSBinopReduction r(this, node); |
| 426 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 429 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 427 r.ConvertInputsToNumber(frame_state); | 430 r.ConvertInputsToNumberOrUndefined(frame_state); |
| 428 r.ConvertInputsToUI32(kSigned, kSigned); | 431 r.ConvertInputsToUI32(kSigned, kSigned); |
| 429 return r.ChangeToPureOperator(intOp, Type::Integral32()); | 432 return r.ChangeToPureOperator(intOp, Type::Integral32()); |
| 430 } | 433 } |
| 431 | 434 |
| 432 | 435 |
| 433 Reduction JSTypedLowering::ReduceUI32Shift(Node* node, | 436 Reduction JSTypedLowering::ReduceUI32Shift(Node* node, |
| 434 Signedness left_signedness, | 437 Signedness left_signedness, |
| 435 const Operator* shift_op) { | 438 const Operator* shift_op) { |
| 436 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 439 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 437 | 440 |
| 438 JSBinopReduction r(this, node); | 441 JSBinopReduction r(this, node); |
| 439 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 442 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 440 r.ConvertInputsToNumber(frame_state); | 443 // TODO(jarin) FIX |
| 444 r.ConvertInputsToNumberOrUndefined(frame_state); |
| 441 r.ConvertInputsToUI32(left_signedness, kUnsigned); | 445 r.ConvertInputsToUI32(left_signedness, kUnsigned); |
| 442 return r.ChangeToPureOperator(shift_op); | 446 return r.ChangeToPureOperator(shift_op); |
| 443 } | 447 } |
| 444 | 448 |
| 445 | 449 |
| 446 Reduction JSTypedLowering::ReduceJSComparison(Node* node) { | 450 Reduction JSTypedLowering::ReduceJSComparison(Node* node) { |
| 447 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 451 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 448 | 452 |
| 449 JSBinopReduction r(this, node); | 453 JSBinopReduction r(this, node); |
| 450 if (r.BothInputsAre(Type::String())) { | 454 if (r.BothInputsAre(Type::String())) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 476 const Operator* less_than_or_equal; | 480 const Operator* less_than_or_equal; |
| 477 if (r.BothInputsAre(Type::Unsigned32())) { | 481 if (r.BothInputsAre(Type::Unsigned32())) { |
| 478 less_than = machine()->Uint32LessThan(); | 482 less_than = machine()->Uint32LessThan(); |
| 479 less_than_or_equal = machine()->Uint32LessThanOrEqual(); | 483 less_than_or_equal = machine()->Uint32LessThanOrEqual(); |
| 480 } else if (r.BothInputsAre(Type::Signed32())) { | 484 } else if (r.BothInputsAre(Type::Signed32())) { |
| 481 less_than = machine()->Int32LessThan(); | 485 less_than = machine()->Int32LessThan(); |
| 482 less_than_or_equal = machine()->Int32LessThanOrEqual(); | 486 less_than_or_equal = machine()->Int32LessThanOrEqual(); |
| 483 } else { | 487 } else { |
| 484 // TODO(turbofan): mixed signed/unsigned int32 comparisons. | 488 // TODO(turbofan): mixed signed/unsigned int32 comparisons. |
| 485 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 489 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 486 r.ConvertInputsToNumber(frame_state); | 490 // TODO(jarin) FIX |
| 491 r.ConvertInputsToNumberOrUndefined(frame_state); |
| 487 less_than = simplified()->NumberLessThan(); | 492 less_than = simplified()->NumberLessThan(); |
| 488 less_than_or_equal = simplified()->NumberLessThanOrEqual(); | 493 less_than_or_equal = simplified()->NumberLessThanOrEqual(); |
| 489 } | 494 } |
| 490 const Operator* comparison; | 495 const Operator* comparison; |
| 491 switch (node->opcode()) { | 496 switch (node->opcode()) { |
| 492 case IrOpcode::kJSLessThan: | 497 case IrOpcode::kJSLessThan: |
| 493 comparison = less_than; | 498 comparison = less_than; |
| 494 break; | 499 break; |
| 495 case IrOpcode::kJSGreaterThan: | 500 case IrOpcode::kJSGreaterThan: |
| 496 comparison = less_than; | 501 comparison = less_than; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 simplified()->ReferenceEqual(Type::Receiver()), invert); | 603 simplified()->ReferenceEqual(Type::Receiver()), invert); |
| 599 } | 604 } |
| 600 if (r.BothInputsAre(Type::Unique())) { | 605 if (r.BothInputsAre(Type::Unique())) { |
| 601 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()), | 606 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()), |
| 602 invert); | 607 invert); |
| 603 } | 608 } |
| 604 if (r.BothInputsAre(Type::String())) { | 609 if (r.BothInputsAre(Type::String())) { |
| 605 return r.ChangeToStringComparisonOperator(simplified()->StringEqual(), | 610 return r.ChangeToStringComparisonOperator(simplified()->StringEqual(), |
| 606 invert); | 611 invert); |
| 607 } | 612 } |
| 608 if (r.BothInputsAre(Type::Number())) { | 613 if (r.BothInputsAre(Type::NumberOrUndefined())) { |
| 609 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); | 614 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); |
| 610 } | 615 } |
| 611 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) | 616 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) |
| 612 return NoChange(); | 617 return NoChange(); |
| 613 } | 618 } |
| 614 | 619 |
| 615 | 620 |
| 616 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { | 621 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { |
| 617 Node* const input = node->InputAt(0); | 622 Node* const input = node->InputAt(0); |
| 618 Type* const input_type = NodeProperties::GetType(input); | 623 Type* const input_type = NodeProperties::GetType(input); |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) { | 1010 key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) { |
| 1006 // JSLoadProperty(typed-array, int32) | 1011 // JSLoadProperty(typed-array, int32) |
| 1007 Handle<FixedTypedArrayBase> elements = | 1012 Handle<FixedTypedArrayBase> elements = |
| 1008 Handle<FixedTypedArrayBase>::cast(handle(array->elements())); | 1013 Handle<FixedTypedArrayBase>::cast(handle(array->elements())); |
| 1009 Node* buffer = jsgraph()->PointerConstant(elements->external_pointer()); | 1014 Node* buffer = jsgraph()->PointerConstant(elements->external_pointer()); |
| 1010 Node* length = jsgraph()->Constant(byte_length); | 1015 Node* length = jsgraph()->Constant(byte_length); |
| 1011 Node* context = NodeProperties::GetContextInput(node); | 1016 Node* context = NodeProperties::GetContextInput(node); |
| 1012 Node* effect = NodeProperties::GetEffectInput(node); | 1017 Node* effect = NodeProperties::GetEffectInput(node); |
| 1013 Node* control = NodeProperties::GetControlInput(node); | 1018 Node* control = NodeProperties::GetControlInput(node); |
| 1014 // Convert to a number first. | 1019 // Convert to a number first. |
| 1015 if (!value_type->Is(Type::Number())) { | 1020 if (!value_type->Is(Type::NumberOrUndefined())) { |
| 1016 Reduction number_reduction = ReduceJSToNumberInput(value); | 1021 Reduction number_reduction = ReduceJSToNumberInput(value); |
| 1017 if (number_reduction.Changed()) { | 1022 if (number_reduction.Changed()) { |
| 1018 value = number_reduction.replacement(); | 1023 value = number_reduction.replacement(); |
| 1019 } else { | 1024 } else { |
| 1020 Node* frame_state_for_to_number = | 1025 Node* frame_state_for_to_number = |
| 1021 NodeProperties::GetFrameStateInput(node, 1); | 1026 NodeProperties::GetFrameStateInput(node, 1); |
| 1022 value = effect = | 1027 value = effect = |
| 1023 graph()->NewNode(javascript()->ToNumber(), value, context, | 1028 graph()->NewNode(javascript()->ToNumber(), value, context, |
| 1024 frame_state_for_to_number, effect, control); | 1029 frame_state_for_to_number, effect, control); |
| 1025 } | 1030 } |
| (...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1807 } | 1812 } |
| 1808 | 1813 |
| 1809 | 1814 |
| 1810 CompilationDependencies* JSTypedLowering::dependencies() const { | 1815 CompilationDependencies* JSTypedLowering::dependencies() const { |
| 1811 return dependencies_; | 1816 return dependencies_; |
| 1812 } | 1817 } |
| 1813 | 1818 |
| 1814 } // namespace compiler | 1819 } // namespace compiler |
| 1815 } // namespace internal | 1820 } // namespace internal |
| 1816 } // namespace v8 | 1821 } // namespace v8 |
| OLD | NEW |