From: mvstanton@chromium.org Date: Wed, 13 Nov 2013 10:07:04 +0000 (+0000) Subject: Simplify behavior of code stubs that accept a variable number of stack X-Git-Tag: upstream/4.7.83~11775 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9d6dddb9aebdc26174f858c7585f363e27f828ad;p=platform%2Fupstream%2Fv8.git Simplify behavior of code stubs that accept a variable number of stack arguments in addition to their parameters. Before, we'd add a special variable to the environment with the value of a register with the number of arguments. Now, that register just appears as a parameter to the code stub. BUG= R=verwaest@chromium.org Review URL: https://codereview.chromium.org/70203002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17680 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 2607f9e..94e114f 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -189,14 +189,21 @@ static void InitializeArrayConstructorDescriptor( // r0 -- number of arguments // r1 -- function // r2 -- type info cell with elements kind - static Register registers[] = { r1, r2 }; - descriptor->register_param_count_ = 2; - if (constant_stack_parameter_count != 0) { + static Register registers_variable_args[] = { r1, r2, r0 }; + static Register registers_no_args[] = { r1, r2 }; + + if (constant_stack_parameter_count == 0) { + descriptor->register_param_count_ = 2; + descriptor->register_params_ = registers_no_args; + } else { // stack param count needs (constructor pointer, and single argument) + descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; descriptor->stack_parameter_count_ = r0; + descriptor->register_param_count_ = 3; + descriptor->register_params_ = registers_variable_args; } + descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; - descriptor->register_params_ = registers; descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; @@ -210,15 +217,21 @@ static void InitializeInternalArrayConstructorDescriptor( // register state // r0 -- number of arguments // r1 -- constructor function - static Register registers[] = { r1 }; - descriptor->register_param_count_ = 1; + static Register registers_variable_args[] = { r1, r0 }; + static Register registers_no_args[] = { r1 }; - if (constant_stack_parameter_count != 0) { + if (constant_stack_parameter_count == 0) { + descriptor->register_param_count_ = 1; + descriptor->register_params_ = registers_no_args; + } else { // stack param count needs (constructor pointer, and single argument) + descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; descriptor->stack_parameter_count_ = r0; + descriptor->register_param_count_ = 2; + descriptor->register_params_ = registers_variable_args; } + descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; - descriptor->register_params_ = registers; descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc index 9339c5f..c846f98 100644 --- a/src/arm/deoptimizer-arm.cc +++ b/src/arm/deoptimizer-arm.cc @@ -107,7 +107,7 @@ void Deoptimizer::SetPlatformCompiledStubRegisters( ApiFunction function(descriptor->deoptimization_handler_); ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_); intptr_t handler = reinterpret_cast(xref.address()); - int params = descriptor->environment_length(); + int params = descriptor->GetHandlerParameterCount(); output_frame->SetRegister(r0.code(), params); output_frame->SetRegister(r1.code(), handler); } diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 480cf98..787fc81 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -2499,7 +2499,7 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { CodeStubInterfaceDescriptor* descriptor = info()->code_stub()->GetInterfaceDescriptor(info()->isolate()); int index = static_cast(instr->index()); - Register reg = DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index); + Register reg = descriptor->GetParameterRegister(index); return DefineFixed(result, reg); } } diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 76786d1..a790179 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -150,26 +150,24 @@ bool CodeStubGraphBuilderBase::BuildGraph() { next_block->SetJoinId(BailoutId::StubEntry()); set_current_block(next_block); + bool runtime_stack_params = descriptor_->stack_parameter_count_.is_valid(); + HInstruction* stack_parameter_count = NULL; for (int i = 0; i < param_count; ++i) { - HParameter* param = - Add(i, HParameter::REGISTER_PARAMETER); + Representation r = descriptor_->IsParameterCountRegister(i) + ? Representation::Integer32() + : Representation::Tagged(); + HParameter* param = Add(i, HParameter::REGISTER_PARAMETER, r); start_environment->Bind(i, param); parameters_[i] = param; + if (descriptor_->IsParameterCountRegister(i)) { + param->set_type(HType::Smi()); + stack_parameter_count = param; + arguments_length_ = stack_parameter_count; + } } - HInstruction* stack_parameter_count; - if (descriptor_->stack_parameter_count_.is_valid()) { - ASSERT(descriptor_->environment_length() == (param_count + 1)); - stack_parameter_count = New(param_count, - HParameter::REGISTER_PARAMETER, - Representation::Integer32()); - stack_parameter_count->set_type(HType::Smi()); - // It's essential to bind this value to the environment in case of deopt. - AddInstruction(stack_parameter_count); - start_environment->Bind(param_count, stack_parameter_count); - arguments_length_ = stack_parameter_count; - } else { - ASSERT(descriptor_->environment_length() == param_count); + ASSERT(!runtime_stack_params || arguments_length_ != NULL); + if (!runtime_stack_params) { stack_parameter_count = graph()->GetConstantMinus1(); arguments_length_ = graph()->GetConstant0(); } @@ -189,10 +187,11 @@ bool CodeStubGraphBuilderBase::BuildGraph() { if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) { if (!stack_parameter_count->IsConstant() && descriptor_->hint_stack_parameter_count_ < 0) { - HInstruction* amount = graph()->GetConstant1(); - stack_pop_count = Add(stack_parameter_count, amount); - stack_pop_count->ChangeRepresentation(Representation::Integer32()); + HInstruction* constant_one = graph()->GetConstant1(); + stack_pop_count = Add(stack_parameter_count, constant_one); stack_pop_count->ClearFlag(HValue::kCanOverflow); + // TODO(mvstanton): verify that stack_parameter_count+1 really fits in a + // smi. } else { int count = descriptor_->hint_stack_parameter_count_; stack_pop_count = Add(count); diff --git a/src/code-stubs.cc b/src/code-stubs.cc index e76bed3..f6e880f 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -46,6 +46,7 @@ CodeStubInterfaceDescriptor::CodeStubInterfaceDescriptor() function_mode_(NOT_JS_FUNCTION_STUB_MODE), register_params_(NULL), deoptimization_handler_(NULL), + handler_arguments_mode_(DONT_PASS_ARGUMENTS), miss_handler_(), has_miss_handler_(false) { } diff --git a/src/code-stubs.h b/src/code-stubs.h index b56a3ec..8f1b686 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -277,23 +277,23 @@ class PlatformCodeStub : public CodeStub { enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; - +enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; struct CodeStubInterfaceDescriptor { CodeStubInterfaceDescriptor(); int register_param_count_; + Register stack_parameter_count_; // if hint_stack_parameter_count_ > 0, the code stub can optimize the // return sequence. Default value is -1, which means it is ignored. int hint_stack_parameter_count_; StubFunctionMode function_mode_; Register* register_params_; + Address deoptimization_handler_; + HandlerArgumentsMode handler_arguments_mode_; int environment_length() const { - if (stack_parameter_count_.is_valid()) { - return register_param_count_ + 1; - } return register_param_count_; } @@ -302,6 +302,9 @@ struct CodeStubInterfaceDescriptor { void SetMissHandler(ExternalReference handler) { miss_handler_ = handler; has_miss_handler_ = true; + // Our miss handler infrastructure doesn't currently support + // variable stack parameter counts. + ASSERT(!stack_parameter_count_.is_valid()); } ExternalReference miss_handler() { @@ -313,18 +316,27 @@ struct CodeStubInterfaceDescriptor { return has_miss_handler_; } + Register GetParameterRegister(int index) { + return register_params_[index]; + } + + bool IsParameterCountRegister(int index) { + return GetParameterRegister(index).is(stack_parameter_count_); + } + + int GetHandlerParameterCount() { + int params = environment_length(); + if (handler_arguments_mode_ == PASS_ARGUMENTS) { + params += 1; + } + return params; + } + private: ExternalReference miss_handler_; bool has_miss_handler_; }; -// A helper to make up for the fact that type Register is not fully -// defined outside of the platform directories -#define DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index) \ - ((index) == (descriptor)->register_param_count_) \ - ? (descriptor)->stack_parameter_count_ \ - : (descriptor)->register_params_[(index)] - class HydrogenCodeStub : public CodeStub { public: diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index 4f2cd03..ef4e39e 100644 --- a/src/deoptimizer.cc +++ b/src/deoptimizer.cc @@ -1586,15 +1586,34 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, } // Copy the register parameters to the failure frame. + int arguments_length_offset = -1; for (int i = 0; i < descriptor->register_param_count_; ++i) { output_frame_offset -= kPointerSize; DoTranslateCommand(iterator, 0, output_frame_offset); + + if (!arg_count_known && descriptor->IsParameterCountRegister(i)) { + arguments_length_offset = output_frame_offset; + } } + ASSERT(0 == output_frame_offset); + if (!arg_count_known) { - DoTranslateCommand(iterator, 0, length_frame_offset, - TRANSLATED_VALUE_IS_NATIVE); - caller_arg_count = output_frame->GetFrameSlot(length_frame_offset); + ASSERT(arguments_length_offset >= 0); + // We know it's a smi because 1) the code stub guarantees the stack + // parameter count is in smi range, and 2) the DoTranslateCommand in the + // parameter loop above translated that to a tagged value. + Smi* smi_caller_arg_count = reinterpret_cast( + output_frame->GetFrameSlot(arguments_length_offset)); + caller_arg_count = smi_caller_arg_count->value(); + output_frame->SetFrameSlot(length_frame_offset, caller_arg_count); + if (trace_scope_ != NULL) { + PrintF(trace_scope_->file(), + " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; args.length\n", + top_address + length_frame_offset, length_frame_offset, + caller_arg_count); + } value = frame_ptr + StandardFrameConstants::kCallerSPOffset + (caller_arg_count - 1) * kPointerSize; output_frame->SetFrameSlot(args_arguments_offset, value); @@ -1602,12 +1621,11 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, PrintF(trace_scope_->file(), " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; args.arguments\n", - top_address + args_arguments_offset, args_arguments_offset, value); + top_address + args_arguments_offset, args_arguments_offset, + value); } } - ASSERT(0 == output_frame_offset); - // Copy the double registers from the input into the output frame. CopyDoubleRegisters(output_frame); @@ -1874,10 +1892,8 @@ void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( #endif -static const char* TraceValueType(bool is_smi, bool is_native = false) { - if (is_native) { - return "native"; - } else if (is_smi) { +static const char* TraceValueType(bool is_smi) { + if (is_smi) { return "smi"; } @@ -2146,13 +2162,11 @@ void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, - int frame_index, - unsigned output_offset, - DeoptimizerTranslatedValueType value_type) { + int frame_index, + unsigned output_offset) { disasm::NameConverter converter; // A GC-safe temporary placeholder that we can put in the output frame. const intptr_t kPlaceholder = reinterpret_cast(Smi::FromInt(0)); - bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE; Translation::Opcode opcode = static_cast(iterator->Next()); @@ -2190,8 +2204,7 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, case Translation::INT32_REGISTER: { int input_reg = iterator->Next(); intptr_t value = input_->GetRegister(input_reg); - bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && - Smi::IsValid(value); + bool is_smi = Smi::IsValid(value); if (trace_scope_ != NULL) { PrintF( trace_scope_->file(), @@ -2200,18 +2213,15 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, output_offset, value, converter.NameOfCPURegister(input_reg), - TraceValueType(is_smi, is_native)); + TraceValueType(is_smi)); } if (is_smi) { intptr_t tagged_value = reinterpret_cast(Smi::FromInt(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, tagged_value); - } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { - output_[frame_index]->SetFrameSlot(output_offset, value); } else { // We save the untagged value on the side and store a GC-safe // temporary placeholder in the frame. - ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); AddDoubleValue(output_[frame_index]->GetTop() + output_offset, static_cast(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); @@ -2222,8 +2232,7 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, case Translation::UINT32_REGISTER: { int input_reg = iterator->Next(); uintptr_t value = static_cast(input_->GetRegister(input_reg)); - bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && - (value <= static_cast(Smi::kMaxValue)); + bool is_smi = value <= static_cast(Smi::kMaxValue); if (trace_scope_ != NULL) { PrintF( trace_scope_->file(), @@ -2233,18 +2242,15 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, output_offset, value, converter.NameOfCPURegister(input_reg), - TraceValueType(is_smi, is_native)); + TraceValueType(is_smi)); } if (is_smi) { intptr_t tagged_value = reinterpret_cast(Smi::FromInt(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, tagged_value); - } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { - output_[frame_index]->SetFrameSlot(output_offset, value); } else { // We save the untagged value on the side and store a GC-safe // temporary placeholder in the frame. - ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); AddDoubleValue(output_[frame_index]->GetTop() + output_offset, static_cast(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); @@ -2295,8 +2301,7 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, int input_slot_index = iterator->Next(); unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); intptr_t value = input_->GetFrameSlot(input_offset); - bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && - Smi::IsValid(value); + bool is_smi = Smi::IsValid(value); if (trace_scope_ != NULL) { PrintF(trace_scope_->file(), " 0x%08" V8PRIxPTR ": ", @@ -2306,18 +2311,15 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, output_offset, value, input_offset, - TraceValueType(is_smi, is_native)); + TraceValueType(is_smi)); } if (is_smi) { intptr_t tagged_value = reinterpret_cast(Smi::FromInt(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, tagged_value); - } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { - output_[frame_index]->SetFrameSlot(output_offset, value); } else { // We save the untagged value on the side and store a GC-safe // temporary placeholder in the frame. - ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); AddDoubleValue(output_[frame_index]->GetTop() + output_offset, static_cast(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); @@ -2330,8 +2332,7 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, unsigned input_offset = input_->GetOffsetFromSlotIndex(input_slot_index); uintptr_t value = static_cast(input_->GetFrameSlot(input_offset)); - bool is_smi = (value_type == TRANSLATED_VALUE_IS_TAGGED) && - (value <= static_cast(Smi::kMaxValue)); + bool is_smi = value <= static_cast(Smi::kMaxValue); if (trace_scope_ != NULL) { PrintF(trace_scope_->file(), " 0x%08" V8PRIxPTR ": ", @@ -2341,18 +2342,15 @@ void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, output_offset, value, input_offset, - TraceValueType(is_smi, is_native)); + TraceValueType(is_smi)); } if (is_smi) { intptr_t tagged_value = reinterpret_cast(Smi::FromInt(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, tagged_value); - } else if (value_type == TRANSLATED_VALUE_IS_NATIVE) { - output_[frame_index]->SetFrameSlot(output_offset, value); } else { // We save the untagged value on the side and store a GC-safe // temporary placeholder in the frame. - ASSERT(value_type == TRANSLATED_VALUE_IS_TAGGED); AddDoubleValue(output_[frame_index]->GetTop() + output_offset, static_cast(static_cast(value))); output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); diff --git a/src/deoptimizer.h b/src/deoptimizer.h index f5530a8..52e4e24 100644 --- a/src/deoptimizer.h +++ b/src/deoptimizer.h @@ -333,15 +333,9 @@ class Deoptimizer : public Malloced { int object_index, int field_index); - enum DeoptimizerTranslatedValueType { - TRANSLATED_VALUE_IS_NATIVE, - TRANSLATED_VALUE_IS_TAGGED - }; - void DoTranslateCommand(TranslationIterator* iterator, - int frame_index, - unsigned output_offset, - DeoptimizerTranslatedValueType value_type = TRANSLATED_VALUE_IS_TAGGED); + int frame_index, + unsigned output_offset); unsigned ComputeInputFrameSize() const; unsigned ComputeFixedSize(JSFunction* function) const; diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 264e300..adc2d50 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -168,15 +168,21 @@ static void InitializeArrayConstructorDescriptor( // eax -- number of arguments // edi -- function // ebx -- type info cell with elements kind - static Register registers[] = { edi, ebx }; - descriptor->register_param_count_ = 2; + static Register registers_variable_args[] = { edi, ebx, eax }; + static Register registers_no_args[] = { edi, ebx }; - if (constant_stack_parameter_count != 0) { + if (constant_stack_parameter_count == 0) { + descriptor->register_param_count_ = 2; + descriptor->register_params_ = registers_no_args; + } else { // stack param count needs (constructor pointer, and single argument) + descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; descriptor->stack_parameter_count_ = eax; + descriptor->register_param_count_ = 3; + descriptor->register_params_ = registers_variable_args; } + descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; - descriptor->register_params_ = registers; descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; @@ -190,15 +196,21 @@ static void InitializeInternalArrayConstructorDescriptor( // register state // eax -- number of arguments // edi -- constructor function - static Register registers[] = { edi }; - descriptor->register_param_count_ = 1; + static Register registers_variable_args[] = { edi, eax }; + static Register registers_no_args[] = { edi }; - if (constant_stack_parameter_count != 0) { + if (constant_stack_parameter_count == 0) { + descriptor->register_param_count_ = 1; + descriptor->register_params_ = registers_no_args; + } else { // stack param count needs (constructor pointer, and single argument) + descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; descriptor->stack_parameter_count_ = eax; + descriptor->register_param_count_ = 2; + descriptor->register_params_ = registers_variable_args; } + descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; - descriptor->register_params_ = registers; descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc index e339b3a..e043aa4 100644 --- a/src/ia32/deoptimizer-ia32.cc +++ b/src/ia32/deoptimizer-ia32.cc @@ -202,7 +202,7 @@ void Deoptimizer::SetPlatformCompiledStubRegisters( FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) { intptr_t handler = reinterpret_cast(descriptor->deoptimization_handler_); - int params = descriptor->environment_length(); + int params = descriptor->GetHandlerParameterCount(); output_frame->SetRegister(eax.code(), params); output_frame->SetRegister(ebx.code(), handler); } diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index b7818c8..29b42fe 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -2569,7 +2569,7 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { CodeStubInterfaceDescriptor* descriptor = info()->code_stub()->GetInterfaceDescriptor(info()->isolate()); int index = static_cast(instr->index()); - Register reg = DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index); + Register reg = descriptor->GetParameterRegister(index); return DefineFixed(result, reg); } } diff --git a/src/runtime.cc b/src/runtime.cc index 348e1df..cd2c123 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -14734,18 +14734,25 @@ static MaybeObject* ArrayConstructorCommon(Isolate* isolate, RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) { HandleScope scope(isolate); // If we get 2 arguments then they are the stub parameters (constructor, type - // info). If we get 3, then the first one is a pointer to the arguments - // passed by the caller. + // info). If we get 4, then the first one is a pointer to the arguments + // passed by the caller, and the last one is the length of the arguments + // passed to the caller (redundant, but useful to check on the deoptimizer + // with an assert). Arguments empty_args(0, NULL); bool no_caller_args = args.length() == 2; - ASSERT(no_caller_args || args.length() == 3); + ASSERT(no_caller_args || args.length() == 4); int parameters_start = no_caller_args ? 0 : 1; Arguments* caller_args = no_caller_args ? &empty_args : reinterpret_cast(args[0]); CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1); - +#ifdef DEBUG + if (!no_caller_args) { + CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2); + ASSERT(arg_count == caller_args->length()); + } +#endif return ArrayConstructorCommon(isolate, constructor, type_info, @@ -14757,13 +14764,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) { HandleScope scope(isolate); Arguments empty_args(0, NULL); bool no_caller_args = args.length() == 1; - ASSERT(no_caller_args || args.length() == 2); + ASSERT(no_caller_args || args.length() == 3); int parameters_start = no_caller_args ? 0 : 1; Arguments* caller_args = no_caller_args ? &empty_args : reinterpret_cast(args[0]); CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); - +#ifdef DEBUG + if (!no_caller_args) { + CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1); + ASSERT(arg_count == caller_args->length()); + } +#endif return ArrayConstructorCommon(isolate, constructor, Handle::null(), diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 0912661..9d95fc4 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -176,14 +176,21 @@ static void InitializeArrayConstructorDescriptor( // rax -- number of arguments // rdi -- function // rbx -- type info cell with elements kind - static Register registers[] = { rdi, rbx }; - descriptor->register_param_count_ = 2; - if (constant_stack_parameter_count != 0) { + static Register registers_variable_args[] = { rdi, rbx, rax }; + static Register registers_no_args[] = { rdi, rbx }; + + if (constant_stack_parameter_count == 0) { + descriptor->register_param_count_ = 2; + descriptor->register_params_ = registers_no_args; + } else { // stack param count needs (constructor pointer, and single argument) + descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; descriptor->stack_parameter_count_ = rax; + descriptor->register_param_count_ = 3; + descriptor->register_params_ = registers_variable_args; } + descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; - descriptor->register_params_ = registers; descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; @@ -197,15 +204,21 @@ static void InitializeInternalArrayConstructorDescriptor( // register state // rax -- number of arguments // rdi -- constructor function - static Register registers[] = { rdi }; - descriptor->register_param_count_ = 1; + static Register registers_variable_args[] = { rdi, rax }; + static Register registers_no_args[] = { rdi }; - if (constant_stack_parameter_count != 0) { + if (constant_stack_parameter_count == 0) { + descriptor->register_param_count_ = 1; + descriptor->register_params_ = registers_no_args; + } else { // stack param count needs (constructor pointer, and single argument) + descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; descriptor->stack_parameter_count_ = rax; + descriptor->register_param_count_ = 2; + descriptor->register_params_ = registers_variable_args; } + descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; - descriptor->register_params_ = registers; descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc index bf11e08..4528077 100644 --- a/src/x64/deoptimizer-x64.cc +++ b/src/x64/deoptimizer-x64.cc @@ -106,7 +106,7 @@ void Deoptimizer::SetPlatformCompiledStubRegisters( FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) { intptr_t handler = reinterpret_cast(descriptor->deoptimization_handler_); - int params = descriptor->environment_length(); + int params = descriptor->GetHandlerParameterCount(); output_frame->SetRegister(rax.code(), params); output_frame->SetRegister(rbx.code(), handler); } diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 530f153..a121646 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -2422,7 +2422,7 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { CodeStubInterfaceDescriptor* descriptor = info()->code_stub()->GetInterfaceDescriptor(info()->isolate()); int index = static_cast(instr->index()); - Register reg = DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index); + Register reg = descriptor->GetParameterRegister(index); return DefineFixed(result, reg); } }