Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/deoptimizer.h" | 5 #include "src/deoptimizer.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 701 | 701 |
| 702 BailoutId node_id = input_data->AstId(bailout_id_); | 702 BailoutId node_id = input_data->AstId(bailout_id_); |
| 703 ByteArray* translations = input_data->TranslationByteArray(); | 703 ByteArray* translations = input_data->TranslationByteArray(); |
| 704 unsigned translation_index = | 704 unsigned translation_index = |
| 705 input_data->TranslationIndex(bailout_id_)->value(); | 705 input_data->TranslationIndex(bailout_id_)->value(); |
| 706 | 706 |
| 707 TranslationIterator state_iterator(translations, translation_index); | 707 TranslationIterator state_iterator(translations, translation_index); |
| 708 translated_state_.Init( | 708 translated_state_.Init( |
| 709 input_->GetFramePointerAddress(), &state_iterator, | 709 input_->GetFramePointerAddress(), &state_iterator, |
| 710 input_data->LiteralArray(), input_->GetRegisterValues(), | 710 input_data->LiteralArray(), input_->GetRegisterValues(), |
| 711 trace_scope_ == nullptr ? nullptr : trace_scope_->file()); | 711 trace_scope_ == nullptr ? nullptr : trace_scope_->file(), |
| 712 function_ ? function_->shared()->internal_formal_parameter_count() : 0); | |
| 712 | 713 |
| 713 // Do the input frame to output frame(s) translation. | 714 // Do the input frame to output frame(s) translation. |
| 714 size_t count = translated_state_.frames().size(); | 715 size_t count = translated_state_.frames().size(); |
| 715 // If we are supposed to go to the catch handler, find the catching frame | 716 // If we are supposed to go to the catch handler, find the catching frame |
| 716 // for the catch and make sure we only deoptimize upto that frame. | 717 // for the catch and make sure we only deoptimize upto that frame. |
| 717 if (deoptimizing_throw_) { | 718 if (deoptimizing_throw_) { |
| 718 size_t catch_handler_frame_index = count; | 719 size_t catch_handler_frame_index = count; |
| 719 for (size_t i = count; i-- > 0;) { | 720 for (size_t i = count; i-- > 0;) { |
| 720 catch_handler_pc_offset_ = LookupCatchHandler( | 721 catch_handler_pc_offset_ = LookupCatchHandler( |
| 721 &(translated_state_.frames()[i]), &catch_handler_data_); | 722 &(translated_state_.frames()[i]), &catch_handler_data_); |
| (...skipping 1672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2394 buffer_->Add(COMPILED_STUB_FRAME); | 2395 buffer_->Add(COMPILED_STUB_FRAME); |
| 2395 buffer_->Add(height); | 2396 buffer_->Add(height); |
| 2396 } | 2397 } |
| 2397 | 2398 |
| 2398 | 2399 |
| 2399 void Translation::BeginArgumentsObject(int args_length) { | 2400 void Translation::BeginArgumentsObject(int args_length) { |
| 2400 buffer_->Add(ARGUMENTS_OBJECT); | 2401 buffer_->Add(ARGUMENTS_OBJECT); |
| 2401 buffer_->Add(args_length); | 2402 buffer_->Add(args_length); |
| 2402 } | 2403 } |
| 2403 | 2404 |
| 2405 void Translation::ArgumentsElements(bool is_rest) { | |
| 2406 buffer_->Add(ARGUMENTS_ELEMENTS); | |
| 2407 buffer_->Add(is_rest); | |
| 2408 } | |
| 2404 | 2409 |
| 2405 void Translation::BeginCapturedObject(int length) { | 2410 void Translation::BeginCapturedObject(int length) { |
| 2406 buffer_->Add(CAPTURED_OBJECT); | 2411 buffer_->Add(CAPTURED_OBJECT); |
| 2407 buffer_->Add(length); | 2412 buffer_->Add(length); |
| 2408 } | 2413 } |
| 2409 | 2414 |
| 2410 | 2415 |
| 2411 void Translation::DuplicateObject(int object_index) { | 2416 void Translation::DuplicateObject(int object_index) { |
| 2412 buffer_->Add(DUPLICATED_OBJECT); | 2417 buffer_->Add(DUPLICATED_OBJECT); |
| 2413 buffer_->Add(object_index); | 2418 buffer_->Add(object_index); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2527 case COMPILED_STUB_FRAME: | 2532 case COMPILED_STUB_FRAME: |
| 2528 case TAIL_CALLER_FRAME: | 2533 case TAIL_CALLER_FRAME: |
| 2529 return 1; | 2534 return 1; |
| 2530 case BEGIN: | 2535 case BEGIN: |
| 2531 case ARGUMENTS_ADAPTOR_FRAME: | 2536 case ARGUMENTS_ADAPTOR_FRAME: |
| 2532 return 2; | 2537 return 2; |
| 2533 case JS_FRAME: | 2538 case JS_FRAME: |
| 2534 case INTERPRETED_FRAME: | 2539 case INTERPRETED_FRAME: |
| 2535 case CONSTRUCT_STUB_FRAME: | 2540 case CONSTRUCT_STUB_FRAME: |
| 2536 return 3; | 2541 return 3; |
| 2542 case ARGUMENTS_ELEMENTS: | |
| 2543 return 1; | |
| 2537 } | 2544 } |
| 2538 FATAL("Unexpected translation type"); | 2545 FATAL("Unexpected translation type"); |
| 2539 return -1; | 2546 return -1; |
| 2540 } | 2547 } |
| 2541 | 2548 |
| 2542 | 2549 |
| 2543 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) | 2550 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) |
| 2544 | 2551 |
| 2545 const char* Translation::StringFor(Opcode opcode) { | 2552 const char* Translation::StringFor(Opcode opcode) { |
| 2546 #define TRANSLATION_OPCODE_CASE(item) case item: return #item; | 2553 #define TRANSLATION_OPCODE_CASE(item) case item: return #item; |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2785 | 2792 |
| 2786 // static | 2793 // static |
| 2787 TranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container, | 2794 TranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container, |
| 2788 int length, | 2795 int length, |
| 2789 int object_index) { | 2796 int object_index) { |
| 2790 TranslatedValue slot(container, kArgumentsObject); | 2797 TranslatedValue slot(container, kArgumentsObject); |
| 2791 slot.materialization_info_ = {object_index, length}; | 2798 slot.materialization_info_ = {object_index, length}; |
| 2792 return slot; | 2799 return slot; |
| 2793 } | 2800 } |
| 2794 | 2801 |
| 2795 | |
| 2796 // static | 2802 // static |
| 2797 TranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container, | 2803 TranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container, |
| 2798 int length, | 2804 int length, |
| 2799 int object_index) { | 2805 int object_index) { |
| 2800 TranslatedValue slot(container, kCapturedObject); | 2806 TranslatedValue slot(container, kCapturedObject); |
| 2801 slot.materialization_info_ = {object_index, length}; | 2807 slot.materialization_info_ = {object_index, length}; |
| 2802 return slot; | 2808 return slot; |
| 2803 } | 2809 } |
| 2804 | 2810 |
| 2805 | 2811 |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3295 PrintF(trace_file, | 3301 PrintF(trace_file, |
| 3296 " reading compiler stub frame => height=%d; inputs:\n", height); | 3302 " reading compiler stub frame => height=%d; inputs:\n", height); |
| 3297 } | 3303 } |
| 3298 return TranslatedFrame::CompiledStubFrame(height, | 3304 return TranslatedFrame::CompiledStubFrame(height, |
| 3299 literal_array->GetIsolate()); | 3305 literal_array->GetIsolate()); |
| 3300 } | 3306 } |
| 3301 | 3307 |
| 3302 case Translation::BEGIN: | 3308 case Translation::BEGIN: |
| 3303 case Translation::DUPLICATED_OBJECT: | 3309 case Translation::DUPLICATED_OBJECT: |
| 3304 case Translation::ARGUMENTS_OBJECT: | 3310 case Translation::ARGUMENTS_OBJECT: |
| 3311 case Translation::ARGUMENTS_ELEMENTS: | |
| 3305 case Translation::CAPTURED_OBJECT: | 3312 case Translation::CAPTURED_OBJECT: |
| 3306 case Translation::REGISTER: | 3313 case Translation::REGISTER: |
| 3307 case Translation::INT32_REGISTER: | 3314 case Translation::INT32_REGISTER: |
| 3308 case Translation::UINT32_REGISTER: | 3315 case Translation::UINT32_REGISTER: |
| 3309 case Translation::BOOL_REGISTER: | 3316 case Translation::BOOL_REGISTER: |
| 3310 case Translation::FLOAT_REGISTER: | 3317 case Translation::FLOAT_REGISTER: |
| 3311 case Translation::DOUBLE_REGISTER: | 3318 case Translation::DOUBLE_REGISTER: |
| 3312 case Translation::STACK_SLOT: | 3319 case Translation::STACK_SLOT: |
| 3313 case Translation::INT32_STACK_SLOT: | 3320 case Translation::INT32_STACK_SLOT: |
| 3314 case Translation::UINT32_STACK_SLOT: | 3321 case Translation::UINT32_STACK_SLOT: |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 3330 while (values_to_skip > 0) { | 3337 while (values_to_skip > 0) { |
| 3331 // Consume the current element. | 3338 // Consume the current element. |
| 3332 values_to_skip--; | 3339 values_to_skip--; |
| 3333 // Add all the children. | 3340 // Add all the children. |
| 3334 values_to_skip += (*iter)->GetChildrenCount(); | 3341 values_to_skip += (*iter)->GetChildrenCount(); |
| 3335 | 3342 |
| 3336 (*iter)++; | 3343 (*iter)++; |
| 3337 } | 3344 } |
| 3338 } | 3345 } |
| 3339 | 3346 |
| 3347 // Creates translated values for an arguments backing store, or the backing | |
| 3348 // store for the rest parameters if {is_rest} is true. The TranslatedValue | |
| 3349 // objects for the fields are not read from the TranslationIterator, but instead | |
| 3350 // created on-the-fly based on dynamic information in the optimized frame. | |
|
Jarin
2017/02/27 13:24:34
Awesome, thanks for the comments here and below!
| |
| 3351 void TranslatedState::CreateArgumentsElementsTranslatedValues( | |
| 3352 int frame_index, Address input_frame_pointer, bool is_rest) { | |
| 3353 TranslatedFrame& frame = frames_[frame_index]; | |
| 3340 | 3354 |
| 3341 // We can't intermix stack decoding and allocations because | 3355 Address parent_frame_pointer = *reinterpret_cast<Address*>( |
| 3342 // deoptimization infrastracture is not GC safe. | 3356 input_frame_pointer + StandardFrameConstants::kCallerFPOffset); |
| 3357 Object* parent_frame_type = *reinterpret_cast<Object**>( | |
| 3358 parent_frame_pointer + CommonFrameConstants::kContextOrFrameTypeOffset); | |
| 3359 int length; | |
| 3360 Address arguments_frame; | |
| 3361 if (parent_frame_type == Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)) { | |
| 3362 length = Smi::cast(*reinterpret_cast<Object**>( | |
| 3363 parent_frame_pointer + | |
| 3364 ArgumentsAdaptorFrameConstants::kLengthOffset)) | |
| 3365 ->value(); | |
| 3366 arguments_frame = parent_frame_pointer; | |
| 3367 } else { | |
| 3368 length = formal_parameter_count_; | |
| 3369 arguments_frame = input_frame_pointer; | |
| 3370 } | |
| 3371 | |
| 3372 if (is_rest) { | |
| 3373 // If the actual number of arguments is less than the number of formal | |
| 3374 // parameters, we have zero rest parameters. | |
| 3375 length = std::max(0, length - formal_parameter_count_); | |
| 3376 } | |
| 3377 | |
| 3378 int object_index = static_cast<int>(object_positions_.size()); | |
| 3379 int value_index = static_cast<int>(frame.values_.size()); | |
| 3380 object_positions_.push_back({frame_index, value_index}); | |
| 3381 frame.Add(TranslatedValue::NewDeferredObject( | |
| 3382 this, length + FixedArray::kHeaderSize / kPointerSize, object_index)); | |
| 3383 | |
| 3384 frame.Add( | |
| 3385 TranslatedValue::NewTagged(this, isolate_->heap()->fixed_array_map())); | |
| 3386 frame.Add(TranslatedValue::NewInt32(this, length)); | |
| 3387 | |
| 3388 for (int i = length - 1; i >= 0; --i) { | |
| 3389 Address argument_slot = arguments_frame + | |
| 3390 CommonFrameConstants::kFixedFrameSizeAboveFp + | |
| 3391 i * kPointerSize; | |
| 3392 frame.Add(TranslatedValue::NewTagged( | |
| 3393 this, *reinterpret_cast<Object**>(argument_slot))); | |
| 3394 } | |
| 3395 } | |
| 3396 | |
| 3397 // We can't intermix stack decoding and allocations because the deoptimization | |
| 3398 // infrastracture is not GC safe. | |
| 3343 // Thus we build a temporary structure in malloced space. | 3399 // Thus we build a temporary structure in malloced space. |
| 3344 TranslatedValue TranslatedState::CreateNextTranslatedValue( | 3400 // The TranslatedValue objects created correspond to the static translation |
| 3345 int frame_index, int value_index, TranslationIterator* iterator, | 3401 // instructions from the TranslationIterator, except for |
| 3346 FixedArray* literal_array, Address fp, RegisterValues* registers, | 3402 // Translation::ARGUMENTS_ELEMENTS, where the number and values of the |
| 3347 FILE* trace_file) { | 3403 // FixedArray elements depend on dynamic information from the optimized frame. |
| 3404 // Returns the number of expected nested translations from the | |
| 3405 // TranslationIterator. | |
| 3406 int TranslatedState::CreateNextTranslatedValue( | |
| 3407 int frame_index, TranslationIterator* iterator, FixedArray* literal_array, | |
| 3408 Address fp, RegisterValues* registers, FILE* trace_file) { | |
| 3348 disasm::NameConverter converter; | 3409 disasm::NameConverter converter; |
| 3349 | 3410 |
| 3411 TranslatedFrame& frame = frames_[frame_index]; | |
| 3412 int value_index = static_cast<int>(frame.values_.size()); | |
| 3413 | |
| 3350 Translation::Opcode opcode = | 3414 Translation::Opcode opcode = |
| 3351 static_cast<Translation::Opcode>(iterator->Next()); | 3415 static_cast<Translation::Opcode>(iterator->Next()); |
| 3352 switch (opcode) { | 3416 switch (opcode) { |
| 3353 case Translation::BEGIN: | 3417 case Translation::BEGIN: |
| 3354 case Translation::JS_FRAME: | 3418 case Translation::JS_FRAME: |
| 3355 case Translation::INTERPRETED_FRAME: | 3419 case Translation::INTERPRETED_FRAME: |
| 3356 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 3420 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 3357 case Translation::TAIL_CALLER_FRAME: | 3421 case Translation::TAIL_CALLER_FRAME: |
| 3358 case Translation::CONSTRUCT_STUB_FRAME: | 3422 case Translation::CONSTRUCT_STUB_FRAME: |
| 3359 case Translation::GETTER_STUB_FRAME: | 3423 case Translation::GETTER_STUB_FRAME: |
| 3360 case Translation::SETTER_STUB_FRAME: | 3424 case Translation::SETTER_STUB_FRAME: |
| 3361 case Translation::COMPILED_STUB_FRAME: | 3425 case Translation::COMPILED_STUB_FRAME: |
| 3362 // Peeled off before getting here. | 3426 // Peeled off before getting here. |
| 3363 break; | 3427 break; |
| 3364 | 3428 |
| 3365 case Translation::DUPLICATED_OBJECT: { | 3429 case Translation::DUPLICATED_OBJECT: { |
| 3366 int object_id = iterator->Next(); | 3430 int object_id = iterator->Next(); |
| 3367 if (trace_file != nullptr) { | 3431 if (trace_file != nullptr) { |
| 3368 PrintF(trace_file, "duplicated object #%d", object_id); | 3432 PrintF(trace_file, "duplicated object #%d", object_id); |
| 3369 } | 3433 } |
| 3370 object_positions_.push_back(object_positions_[object_id]); | 3434 object_positions_.push_back(object_positions_[object_id]); |
| 3371 return TranslatedValue::NewDuplicateObject(this, object_id); | 3435 TranslatedValue translated_value = |
| 3436 TranslatedValue::NewDuplicateObject(this, object_id); | |
| 3437 frame.Add(translated_value); | |
| 3438 return translated_value.GetChildrenCount(); | |
| 3372 } | 3439 } |
| 3373 | 3440 |
| 3374 case Translation::ARGUMENTS_OBJECT: { | 3441 case Translation::ARGUMENTS_OBJECT: { |
| 3375 int arg_count = iterator->Next(); | 3442 int arg_count = iterator->Next(); |
| 3376 int object_index = static_cast<int>(object_positions_.size()); | 3443 int object_index = static_cast<int>(object_positions_.size()); |
| 3377 if (trace_file != nullptr) { | 3444 if (trace_file != nullptr) { |
| 3378 PrintF(trace_file, "argumets object #%d (length = %d)", object_index, | 3445 PrintF(trace_file, "arguments object #%d (length = %d)", object_index, |
| 3379 arg_count); | 3446 arg_count); |
| 3380 } | 3447 } |
| 3381 object_positions_.push_back({frame_index, value_index}); | 3448 object_positions_.push_back({frame_index, value_index}); |
| 3382 return TranslatedValue::NewArgumentsObject(this, arg_count, object_index); | 3449 TranslatedValue translated_value = |
| 3450 TranslatedValue::NewArgumentsObject(this, arg_count, object_index); | |
| 3451 frame.Add(translated_value); | |
| 3452 return translated_value.GetChildrenCount(); | |
| 3453 } | |
| 3454 | |
| 3455 case Translation::ARGUMENTS_ELEMENTS: { | |
| 3456 bool is_rest = iterator->Next(); | |
| 3457 CreateArgumentsElementsTranslatedValues(frame_index, fp, is_rest); | |
| 3458 return 0; | |
| 3383 } | 3459 } |
| 3384 | 3460 |
| 3385 case Translation::CAPTURED_OBJECT: { | 3461 case Translation::CAPTURED_OBJECT: { |
| 3386 int field_count = iterator->Next(); | 3462 int field_count = iterator->Next(); |
| 3387 int object_index = static_cast<int>(object_positions_.size()); | 3463 int object_index = static_cast<int>(object_positions_.size()); |
| 3388 if (trace_file != nullptr) { | 3464 if (trace_file != nullptr) { |
| 3389 PrintF(trace_file, "captured object #%d (length = %d)", object_index, | 3465 PrintF(trace_file, "captured object #%d (length = %d)", object_index, |
| 3390 field_count); | 3466 field_count); |
| 3391 } | 3467 } |
| 3392 object_positions_.push_back({frame_index, value_index}); | 3468 object_positions_.push_back({frame_index, value_index}); |
| 3393 return TranslatedValue::NewDeferredObject(this, field_count, | 3469 TranslatedValue translated_value = |
| 3394 object_index); | 3470 TranslatedValue::NewDeferredObject(this, field_count, object_index); |
| 3471 frame.Add(translated_value); | |
| 3472 return translated_value.GetChildrenCount(); | |
| 3395 } | 3473 } |
| 3396 | 3474 |
| 3397 case Translation::REGISTER: { | 3475 case Translation::REGISTER: { |
| 3398 int input_reg = iterator->Next(); | 3476 int input_reg = iterator->Next(); |
| 3399 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3477 if (registers == nullptr) { |
| 3478 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); | |
| 3479 frame.Add(translated_value); | |
| 3480 return translated_value.GetChildrenCount(); | |
| 3481 } | |
| 3400 intptr_t value = registers->GetRegister(input_reg); | 3482 intptr_t value = registers->GetRegister(input_reg); |
| 3401 if (trace_file != nullptr) { | 3483 if (trace_file != nullptr) { |
| 3402 PrintF(trace_file, "0x%08" V8PRIxPTR " ; %s ", value, | 3484 PrintF(trace_file, "0x%08" V8PRIxPTR " ; %s ", value, |
| 3403 converter.NameOfCPURegister(input_reg)); | 3485 converter.NameOfCPURegister(input_reg)); |
| 3404 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); | 3486 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); |
| 3405 } | 3487 } |
| 3406 return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value)); | 3488 TranslatedValue translated_value = |
| 3489 TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value)); | |
| 3490 frame.Add(translated_value); | |
| 3491 return translated_value.GetChildrenCount(); | |
| 3407 } | 3492 } |
| 3408 | 3493 |
| 3409 case Translation::INT32_REGISTER: { | 3494 case Translation::INT32_REGISTER: { |
| 3410 int input_reg = iterator->Next(); | 3495 int input_reg = iterator->Next(); |
| 3411 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3496 if (registers == nullptr) { |
| 3497 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); | |
| 3498 frame.Add(translated_value); | |
| 3499 return translated_value.GetChildrenCount(); | |
| 3500 } | |
| 3412 intptr_t value = registers->GetRegister(input_reg); | 3501 intptr_t value = registers->GetRegister(input_reg); |
| 3413 if (trace_file != nullptr) { | 3502 if (trace_file != nullptr) { |
| 3414 PrintF(trace_file, "%" V8PRIdPTR " ; %s ", value, | 3503 PrintF(trace_file, "%" V8PRIdPTR " ; %s ", value, |
| 3415 converter.NameOfCPURegister(input_reg)); | 3504 converter.NameOfCPURegister(input_reg)); |
| 3416 } | 3505 } |
| 3417 return TranslatedValue::NewInt32(this, static_cast<int32_t>(value)); | 3506 TranslatedValue translated_value = |
| 3507 TranslatedValue::NewInt32(this, static_cast<int32_t>(value)); | |
| 3508 frame.Add(translated_value); | |
| 3509 return translated_value.GetChildrenCount(); | |
| 3418 } | 3510 } |
| 3419 | 3511 |
| 3420 case Translation::UINT32_REGISTER: { | 3512 case Translation::UINT32_REGISTER: { |
| 3421 int input_reg = iterator->Next(); | 3513 int input_reg = iterator->Next(); |
| 3422 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3514 if (registers == nullptr) { |
| 3515 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); | |
| 3516 frame.Add(translated_value); | |
| 3517 return translated_value.GetChildrenCount(); | |
| 3518 } | |
| 3423 intptr_t value = registers->GetRegister(input_reg); | 3519 intptr_t value = registers->GetRegister(input_reg); |
| 3424 if (trace_file != nullptr) { | 3520 if (trace_file != nullptr) { |
| 3425 PrintF(trace_file, "%" V8PRIuPTR " ; %s (uint)", value, | 3521 PrintF(trace_file, "%" V8PRIuPTR " ; %s (uint)", value, |
| 3426 converter.NameOfCPURegister(input_reg)); | 3522 converter.NameOfCPURegister(input_reg)); |
| 3427 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); | 3523 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); |
| 3428 } | 3524 } |
| 3429 return TranslatedValue::NewUInt32(this, static_cast<uint32_t>(value)); | 3525 TranslatedValue translated_value = |
| 3526 TranslatedValue::NewUInt32(this, static_cast<uint32_t>(value)); | |
| 3527 frame.Add(translated_value); | |
| 3528 return translated_value.GetChildrenCount(); | |
| 3430 } | 3529 } |
| 3431 | 3530 |
| 3432 case Translation::BOOL_REGISTER: { | 3531 case Translation::BOOL_REGISTER: { |
| 3433 int input_reg = iterator->Next(); | 3532 int input_reg = iterator->Next(); |
| 3434 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3533 if (registers == nullptr) { |
| 3534 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); | |
| 3535 frame.Add(translated_value); | |
| 3536 return translated_value.GetChildrenCount(); | |
| 3537 } | |
| 3435 intptr_t value = registers->GetRegister(input_reg); | 3538 intptr_t value = registers->GetRegister(input_reg); |
| 3436 if (trace_file != nullptr) { | 3539 if (trace_file != nullptr) { |
| 3437 PrintF(trace_file, "%" V8PRIdPTR " ; %s (bool)", value, | 3540 PrintF(trace_file, "%" V8PRIdPTR " ; %s (bool)", value, |
| 3438 converter.NameOfCPURegister(input_reg)); | 3541 converter.NameOfCPURegister(input_reg)); |
| 3439 } | 3542 } |
| 3440 return TranslatedValue::NewBool(this, static_cast<uint32_t>(value)); | 3543 TranslatedValue translated_value = |
| 3544 TranslatedValue::NewBool(this, static_cast<uint32_t>(value)); | |
| 3545 frame.Add(translated_value); | |
| 3546 return translated_value.GetChildrenCount(); | |
| 3441 } | 3547 } |
| 3442 | 3548 |
| 3443 case Translation::FLOAT_REGISTER: { | 3549 case Translation::FLOAT_REGISTER: { |
| 3444 int input_reg = iterator->Next(); | 3550 int input_reg = iterator->Next(); |
| 3445 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3551 if (registers == nullptr) { |
| 3552 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); | |
| 3553 frame.Add(translated_value); | |
| 3554 return translated_value.GetChildrenCount(); | |
| 3555 } | |
| 3446 Float32 value = registers->GetFloatRegister(input_reg); | 3556 Float32 value = registers->GetFloatRegister(input_reg); |
| 3447 if (trace_file != nullptr) { | 3557 if (trace_file != nullptr) { |
| 3448 PrintF(trace_file, "%e ; %s (float)", value.get_scalar(), | 3558 PrintF(trace_file, "%e ; %s (float)", value.get_scalar(), |
| 3449 RegisterConfiguration::Crankshaft()->GetFloatRegisterName( | 3559 RegisterConfiguration::Crankshaft()->GetFloatRegisterName( |
| 3450 input_reg)); | 3560 input_reg)); |
| 3451 } | 3561 } |
| 3452 return TranslatedValue::NewFloat(this, value); | 3562 TranslatedValue translated_value = TranslatedValue::NewFloat(this, value); |
| 3563 frame.Add(translated_value); | |
| 3564 return translated_value.GetChildrenCount(); | |
| 3453 } | 3565 } |
| 3454 | 3566 |
| 3455 case Translation::DOUBLE_REGISTER: { | 3567 case Translation::DOUBLE_REGISTER: { |
| 3456 int input_reg = iterator->Next(); | 3568 int input_reg = iterator->Next(); |
| 3457 if (registers == nullptr) return TranslatedValue::NewInvalid(this); | 3569 if (registers == nullptr) { |
| 3570 TranslatedValue translated_value = TranslatedValue::NewInvalid(this); | |
| 3571 frame.Add(translated_value); | |
| 3572 return translated_value.GetChildrenCount(); | |
| 3573 } | |
| 3458 Float64 value = registers->GetDoubleRegister(input_reg); | 3574 Float64 value = registers->GetDoubleRegister(input_reg); |
| 3459 if (trace_file != nullptr) { | 3575 if (trace_file != nullptr) { |
| 3460 PrintF(trace_file, "%e ; %s (double)", value.get_scalar(), | 3576 PrintF(trace_file, "%e ; %s (double)", value.get_scalar(), |
| 3461 RegisterConfiguration::Crankshaft()->GetDoubleRegisterName( | 3577 RegisterConfiguration::Crankshaft()->GetDoubleRegisterName( |
| 3462 input_reg)); | 3578 input_reg)); |
| 3463 } | 3579 } |
| 3464 return TranslatedValue::NewDouble(this, value); | 3580 TranslatedValue translated_value = |
| 3581 TranslatedValue::NewDouble(this, value); | |
| 3582 frame.Add(translated_value); | |
| 3583 return translated_value.GetChildrenCount(); | |
| 3465 } | 3584 } |
| 3466 | 3585 |
| 3467 case Translation::STACK_SLOT: { | 3586 case Translation::STACK_SLOT: { |
| 3468 int slot_offset = | 3587 int slot_offset = |
| 3469 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3588 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
| 3470 intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset)); | 3589 intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset)); |
| 3471 if (trace_file != nullptr) { | 3590 if (trace_file != nullptr) { |
| 3472 PrintF(trace_file, "0x%08" V8PRIxPTR " ; [fp %c %d] ", value, | 3591 PrintF(trace_file, "0x%08" V8PRIxPTR " ; [fp %c %d] ", value, |
| 3473 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); | 3592 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); |
| 3474 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); | 3593 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); |
| 3475 } | 3594 } |
| 3476 return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value)); | 3595 TranslatedValue translated_value = |
| 3596 TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value)); | |
| 3597 frame.Add(translated_value); | |
| 3598 return translated_value.GetChildrenCount(); | |
| 3477 } | 3599 } |
| 3478 | 3600 |
| 3479 case Translation::INT32_STACK_SLOT: { | 3601 case Translation::INT32_STACK_SLOT: { |
| 3480 int slot_offset = | 3602 int slot_offset = |
| 3481 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3603 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
| 3482 uint32_t value = GetUInt32Slot(fp, slot_offset); | 3604 uint32_t value = GetUInt32Slot(fp, slot_offset); |
| 3483 if (trace_file != nullptr) { | 3605 if (trace_file != nullptr) { |
| 3484 PrintF(trace_file, "%d ; (int) [fp %c %d] ", | 3606 PrintF(trace_file, "%d ; (int) [fp %c %d] ", |
| 3485 static_cast<int32_t>(value), slot_offset < 0 ? '-' : '+', | 3607 static_cast<int32_t>(value), slot_offset < 0 ? '-' : '+', |
| 3486 std::abs(slot_offset)); | 3608 std::abs(slot_offset)); |
| 3487 } | 3609 } |
| 3488 return TranslatedValue::NewInt32(this, value); | 3610 TranslatedValue translated_value = TranslatedValue::NewInt32(this, value); |
| 3611 frame.Add(translated_value); | |
| 3612 return translated_value.GetChildrenCount(); | |
| 3489 } | 3613 } |
| 3490 | 3614 |
| 3491 case Translation::UINT32_STACK_SLOT: { | 3615 case Translation::UINT32_STACK_SLOT: { |
| 3492 int slot_offset = | 3616 int slot_offset = |
| 3493 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3617 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
| 3494 uint32_t value = GetUInt32Slot(fp, slot_offset); | 3618 uint32_t value = GetUInt32Slot(fp, slot_offset); |
| 3495 if (trace_file != nullptr) { | 3619 if (trace_file != nullptr) { |
| 3496 PrintF(trace_file, "%u ; (uint) [fp %c %d] ", value, | 3620 PrintF(trace_file, "%u ; (uint) [fp %c %d] ", value, |
| 3497 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); | 3621 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); |
| 3498 } | 3622 } |
| 3499 return TranslatedValue::NewUInt32(this, value); | 3623 TranslatedValue translated_value = |
| 3624 TranslatedValue::NewUInt32(this, value); | |
| 3625 frame.Add(translated_value); | |
| 3626 return translated_value.GetChildrenCount(); | |
| 3500 } | 3627 } |
| 3501 | 3628 |
| 3502 case Translation::BOOL_STACK_SLOT: { | 3629 case Translation::BOOL_STACK_SLOT: { |
| 3503 int slot_offset = | 3630 int slot_offset = |
| 3504 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3631 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
| 3505 uint32_t value = GetUInt32Slot(fp, slot_offset); | 3632 uint32_t value = GetUInt32Slot(fp, slot_offset); |
| 3506 if (trace_file != nullptr) { | 3633 if (trace_file != nullptr) { |
| 3507 PrintF(trace_file, "%u ; (bool) [fp %c %d] ", value, | 3634 PrintF(trace_file, "%u ; (bool) [fp %c %d] ", value, |
| 3508 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); | 3635 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); |
| 3509 } | 3636 } |
| 3510 return TranslatedValue::NewBool(this, value); | 3637 TranslatedValue translated_value = TranslatedValue::NewBool(this, value); |
| 3638 frame.Add(translated_value); | |
| 3639 return translated_value.GetChildrenCount(); | |
| 3511 } | 3640 } |
| 3512 | 3641 |
| 3513 case Translation::FLOAT_STACK_SLOT: { | 3642 case Translation::FLOAT_STACK_SLOT: { |
| 3514 int slot_offset = | 3643 int slot_offset = |
| 3515 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3644 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
| 3516 Float32 value = GetFloatSlot(fp, slot_offset); | 3645 Float32 value = GetFloatSlot(fp, slot_offset); |
| 3517 if (trace_file != nullptr) { | 3646 if (trace_file != nullptr) { |
| 3518 PrintF(trace_file, "%e ; (float) [fp %c %d] ", value.get_scalar(), | 3647 PrintF(trace_file, "%e ; (float) [fp %c %d] ", value.get_scalar(), |
| 3519 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); | 3648 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); |
| 3520 } | 3649 } |
| 3521 return TranslatedValue::NewFloat(this, value); | 3650 TranslatedValue translated_value = TranslatedValue::NewFloat(this, value); |
| 3651 frame.Add(translated_value); | |
| 3652 return translated_value.GetChildrenCount(); | |
| 3522 } | 3653 } |
| 3523 | 3654 |
| 3524 case Translation::DOUBLE_STACK_SLOT: { | 3655 case Translation::DOUBLE_STACK_SLOT: { |
| 3525 int slot_offset = | 3656 int slot_offset = |
| 3526 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); | 3657 OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); |
| 3527 Float64 value = GetDoubleSlot(fp, slot_offset); | 3658 Float64 value = GetDoubleSlot(fp, slot_offset); |
| 3528 if (trace_file != nullptr) { | 3659 if (trace_file != nullptr) { |
| 3529 PrintF(trace_file, "%e ; (double) [fp %c %d] ", value.get_scalar(), | 3660 PrintF(trace_file, "%e ; (double) [fp %c %d] ", value.get_scalar(), |
| 3530 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); | 3661 slot_offset < 0 ? '-' : '+', std::abs(slot_offset)); |
| 3531 } | 3662 } |
| 3532 return TranslatedValue::NewDouble(this, value); | 3663 TranslatedValue translated_value = |
| 3664 TranslatedValue::NewDouble(this, value); | |
| 3665 frame.Add(translated_value); | |
| 3666 return translated_value.GetChildrenCount(); | |
| 3533 } | 3667 } |
| 3534 | 3668 |
| 3535 case Translation::LITERAL: { | 3669 case Translation::LITERAL: { |
| 3536 int literal_index = iterator->Next(); | 3670 int literal_index = iterator->Next(); |
| 3537 Object* value = literal_array->get(literal_index); | 3671 Object* value = literal_array->get(literal_index); |
| 3538 if (trace_file != nullptr) { | 3672 if (trace_file != nullptr) { |
| 3539 PrintF(trace_file, "0x%08" V8PRIxPTR " ; (literal %d) ", | 3673 PrintF(trace_file, "0x%08" V8PRIxPTR " ; (literal %d) ", |
| 3540 reinterpret_cast<intptr_t>(value), literal_index); | 3674 reinterpret_cast<intptr_t>(value), literal_index); |
| 3541 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); | 3675 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); |
| 3542 } | 3676 } |
| 3543 | 3677 |
| 3544 return TranslatedValue::NewTagged(this, value); | 3678 TranslatedValue translated_value = |
| 3679 TranslatedValue::NewTagged(this, value); | |
| 3680 frame.Add(translated_value); | |
| 3681 return translated_value.GetChildrenCount(); | |
| 3545 } | 3682 } |
| 3546 } | 3683 } |
| 3547 | 3684 |
| 3548 FATAL("We should never get here - unexpected deopt info."); | 3685 FATAL("We should never get here - unexpected deopt info."); |
| 3549 return TranslatedValue(nullptr, TranslatedValue::kInvalid); | 3686 TranslatedValue translated_value = |
|
Jarin
2017/02/27 13:24:34
This is unreachable code. Just say "return 0;" her
| |
| 3687 TranslatedValue(nullptr, TranslatedValue::kInvalid); | |
| 3688 frame.Add(translated_value); | |
| 3689 return translated_value.GetChildrenCount(); | |
| 3550 } | 3690 } |
| 3551 | 3691 |
| 3552 | 3692 |
| 3553 TranslatedState::TranslatedState(JavaScriptFrame* frame) | 3693 TranslatedState::TranslatedState(JavaScriptFrame* frame) |
| 3554 : isolate_(nullptr), | 3694 : isolate_(nullptr), |
| 3555 stack_frame_pointer_(nullptr), | 3695 stack_frame_pointer_(nullptr), |
| 3556 has_adapted_arguments_(false) { | 3696 has_adapted_arguments_(false) { |
| 3557 int deopt_index = Safepoint::kNoDeoptimizationIndex; | 3697 int deopt_index = Safepoint::kNoDeoptimizationIndex; |
| 3558 DeoptimizationInputData* data = | 3698 DeoptimizationInputData* data = |
| 3559 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); | 3699 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); |
| 3560 DCHECK(data != nullptr && deopt_index != Safepoint::kNoDeoptimizationIndex); | 3700 DCHECK(data != nullptr && deopt_index != Safepoint::kNoDeoptimizationIndex); |
| 3561 TranslationIterator it(data->TranslationByteArray(), | 3701 TranslationIterator it(data->TranslationByteArray(), |
| 3562 data->TranslationIndex(deopt_index)->value()); | 3702 data->TranslationIndex(deopt_index)->value()); |
| 3563 Init(frame->fp(), &it, data->LiteralArray(), nullptr /* registers */, | 3703 Init(frame->fp(), &it, data->LiteralArray(), nullptr /* registers */, |
| 3564 nullptr /* trace file */); | 3704 nullptr /* trace file */, |
| 3705 frame->function()->shared()->internal_formal_parameter_count()); | |
| 3565 } | 3706 } |
| 3566 | 3707 |
| 3567 | 3708 |
| 3568 TranslatedState::TranslatedState() | 3709 TranslatedState::TranslatedState() |
| 3569 : isolate_(nullptr), | 3710 : isolate_(nullptr), |
| 3570 stack_frame_pointer_(nullptr), | 3711 stack_frame_pointer_(nullptr), |
| 3571 has_adapted_arguments_(false) {} | 3712 has_adapted_arguments_(false) {} |
| 3572 | 3713 |
| 3573 | |
| 3574 void TranslatedState::Init(Address input_frame_pointer, | 3714 void TranslatedState::Init(Address input_frame_pointer, |
| 3575 TranslationIterator* iterator, | 3715 TranslationIterator* iterator, |
| 3576 FixedArray* literal_array, RegisterValues* registers, | 3716 FixedArray* literal_array, RegisterValues* registers, |
| 3577 FILE* trace_file) { | 3717 FILE* trace_file, int formal_parameter_count) { |
| 3578 DCHECK(frames_.empty()); | 3718 DCHECK(frames_.empty()); |
| 3579 | 3719 |
| 3720 formal_parameter_count_ = formal_parameter_count; | |
| 3721 | |
| 3580 isolate_ = literal_array->GetIsolate(); | 3722 isolate_ = literal_array->GetIsolate(); |
| 3581 // Read out the 'header' translation. | 3723 // Read out the 'header' translation. |
| 3582 Translation::Opcode opcode = | 3724 Translation::Opcode opcode = |
| 3583 static_cast<Translation::Opcode>(iterator->Next()); | 3725 static_cast<Translation::Opcode>(iterator->Next()); |
| 3584 CHECK(opcode == Translation::BEGIN); | 3726 CHECK(opcode == Translation::BEGIN); |
| 3585 | 3727 |
| 3586 int count = iterator->Next(); | 3728 int count = iterator->Next(); |
| 3587 iterator->Next(); // Drop JS frames count. | 3729 iterator->Next(); // Drop JS frames count. |
| 3588 | 3730 |
| 3589 frames_.reserve(count); | 3731 frames_.reserve(count); |
| 3590 | 3732 |
| 3591 std::stack<int> nested_counts; | 3733 std::stack<int> nested_counts; |
| 3592 | 3734 |
| 3593 // Read the frames | 3735 // Read the frames |
| 3594 for (int i = 0; i < count; i++) { | 3736 for (int frame_index = 0; frame_index < count; frame_index++) { |
| 3595 // Read the frame descriptor. | 3737 // Read the frame descriptor. |
| 3596 frames_.push_back(CreateNextTranslatedFrame( | 3738 frames_.push_back(CreateNextTranslatedFrame( |
| 3597 iterator, literal_array, input_frame_pointer, trace_file)); | 3739 iterator, literal_array, input_frame_pointer, trace_file)); |
| 3598 TranslatedFrame& frame = frames_.back(); | 3740 TranslatedFrame& frame = frames_.back(); |
| 3599 | 3741 |
| 3600 // Read the values. | 3742 // Read the values. |
| 3601 int values_to_process = frame.GetValueCount(); | 3743 int values_to_process = frame.GetValueCount(); |
| 3602 while (values_to_process > 0 || !nested_counts.empty()) { | 3744 while (values_to_process > 0 || !nested_counts.empty()) { |
| 3603 if (trace_file != nullptr) { | 3745 if (trace_file != nullptr) { |
| 3604 if (nested_counts.empty()) { | 3746 if (nested_counts.empty()) { |
| 3605 // For top level values, print the value number. | 3747 // For top level values, print the value number. |
| 3606 PrintF(trace_file, " %3i: ", | 3748 PrintF(trace_file, " %3i: ", |
| 3607 frame.GetValueCount() - values_to_process); | 3749 frame.GetValueCount() - values_to_process); |
| 3608 } else { | 3750 } else { |
| 3609 // Take care of indenting for nested values. | 3751 // Take care of indenting for nested values. |
| 3610 PrintF(trace_file, " "); | 3752 PrintF(trace_file, " "); |
| 3611 for (size_t j = 0; j < nested_counts.size(); j++) { | 3753 for (size_t j = 0; j < nested_counts.size(); j++) { |
| 3612 PrintF(trace_file, " "); | 3754 PrintF(trace_file, " "); |
| 3613 } | 3755 } |
| 3614 } | 3756 } |
| 3615 } | 3757 } |
| 3616 | 3758 |
| 3617 TranslatedValue value = CreateNextTranslatedValue( | 3759 int nested_count = |
| 3618 i, static_cast<int>(frame.values_.size()), iterator, literal_array, | 3760 CreateNextTranslatedValue(frame_index, iterator, literal_array, |
| 3619 input_frame_pointer, registers, trace_file); | 3761 input_frame_pointer, registers, trace_file); |
| 3620 frame.Add(value); | |
| 3621 | 3762 |
| 3622 if (trace_file != nullptr) { | 3763 if (trace_file != nullptr) { |
| 3623 PrintF(trace_file, "\n"); | 3764 PrintF(trace_file, "\n"); |
| 3624 } | 3765 } |
| 3625 | 3766 |
| 3626 // Update the value count and resolve the nesting. | 3767 // Update the value count and resolve the nesting. |
| 3627 values_to_process--; | 3768 values_to_process--; |
| 3628 int children_count = value.GetChildrenCount(); | 3769 if (nested_count > 0) { |
| 3629 if (children_count > 0) { | |
| 3630 nested_counts.push(values_to_process); | 3770 nested_counts.push(values_to_process); |
| 3631 values_to_process = children_count; | 3771 values_to_process = nested_count; |
| 3632 } else { | 3772 } else { |
| 3633 while (values_to_process == 0 && !nested_counts.empty()) { | 3773 while (values_to_process == 0 && !nested_counts.empty()) { |
| 3634 values_to_process = nested_counts.top(); | 3774 values_to_process = nested_counts.top(); |
| 3635 nested_counts.pop(); | 3775 nested_counts.pop(); |
| 3636 } | 3776 } |
| 3637 } | 3777 } |
| 3638 } | 3778 } |
| 3639 } | 3779 } |
| 3640 | 3780 |
| 3641 CHECK(!iterator->HasNext() || | 3781 CHECK(!iterator->HasNext() || |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4228 CHECK(value_info->IsMaterializedObject()); | 4368 CHECK(value_info->IsMaterializedObject()); |
| 4229 | 4369 |
| 4230 value_info->value_ = | 4370 value_info->value_ = |
| 4231 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4371 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
| 4232 } | 4372 } |
| 4233 } | 4373 } |
| 4234 } | 4374 } |
| 4235 | 4375 |
| 4236 } // namespace internal | 4376 } // namespace internal |
| 4237 } // namespace v8 | 4377 } // namespace v8 |
| OLD | NEW |