From e1a948a6f881127d91d9f5d29a1b860adf189c51 Mon Sep 17 00:00:00 2001 From: "titzer@chromium.org" Date: Wed, 3 Sep 2014 10:13:21 +0000 Subject: [PATCH] Convert Linkage to use MachineSignature. This simplifies the handling of MachineTypes for parameters and returns used in tests, and overall improves the regularity with which they are handled in both tests and in CallDescriptor. R=bmeurer@chromium.org, jarin@chromium.org BUG= Review URL: https://codereview.chromium.org/530783002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23638 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/compiler/arm/code-generator-arm.cc | 13 +- src/compiler/arm/linkage-arm.cc | 23 +- src/compiler/arm64/code-generator-arm64.cc | 15 +- src/compiler/arm64/linkage-arm64.cc | 23 +- src/compiler/common-operator.h | 7 +- src/compiler/graph.cc | 2 +- src/compiler/ia32/code-generator-ia32.cc | 12 +- src/compiler/ia32/linkage-ia32.cc | 22 +- src/compiler/instruction-selector-impl.h | 21 +- src/compiler/instruction-selector-unittest.cc | 6 +- src/compiler/instruction-selector-unittest.h | 83 ++-- src/compiler/instruction-selector.cc | 39 +- src/compiler/linkage-impl.h | 289 ++++++------ src/compiler/linkage.cc | 2 +- src/compiler/linkage.h | 107 +++-- src/compiler/machine-node-factory.h | 28 +- src/compiler/machine-type.h | 70 ++- src/compiler/raw-machine-assembler.cc | 32 +- src/compiler/raw-machine-assembler.h | 25 +- src/compiler/structured-machine-assembler.cc | 21 +- src/compiler/structured-machine-assembler.h | 22 +- src/compiler/x64/code-generator-x64.cc | 12 +- src/compiler/x64/instruction-selector-x64.cc | 4 +- src/compiler/x64/linkage-x64.cc | 22 +- src/objects.h | 631 +++++++++++++------------- test/cctest/compiler/call-tester.h | 46 +- test/cctest/compiler/codegen-tester.h | 21 +- test/cctest/compiler/graph-builder-tester.cc | 33 +- test/cctest/compiler/graph-builder-tester.h | 14 +- test/cctest/compiler/test-codegen-deopt.cc | 51 ++- test/cctest/compiler/test-linkage.cc | 4 +- 31 files changed, 897 insertions(+), 803 deletions(-) diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc index bc11f5a..a0279c6 100644 --- a/src/compiler/arm/code-generator-arm.cc +++ b/src/compiler/arm/code-generator-arm.cc @@ -156,9 +156,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { break; } case kArchCallJSFunction: { - // TODO(jarin) The load of the context should be separated from the call. Register func = i.InputRegister(0); - __ ldr(cp, FieldMemOperand(func, JSFunction::kContextOffset)); + if (FLAG_debug_code) { + // Check the function's context matches the context argument. + __ ldr(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); + __ cmp(cp, kScratchReg); + __ Assert(eq, kWrongFunctionContext); + } __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); __ Call(ip); AddSafepointAndDeopt(instr); @@ -681,8 +685,9 @@ void CodeGenerator::AssembleReturn() { __ Ret(); } else { __ LeaveFrame(StackFrame::MANUAL); - int pop_count = - descriptor->IsJSFunctionCall() ? descriptor->ParameterCount() : 0; + int pop_count = descriptor->IsJSFunctionCall() + ? static_cast(descriptor->JSParameterCount()) + : 0; __ Drop(pop_count); __ Ret(); } diff --git a/src/compiler/arm/linkage-arm.cc b/src/compiler/arm/linkage-arm.cc index 2b08477..f5c246c 100644 --- a/src/compiler/arm/linkage-arm.cc +++ b/src/compiler/arm/linkage-arm.cc @@ -14,7 +14,7 @@ namespace v8 { namespace internal { namespace compiler { -struct LinkageHelperTraits { +struct ArmLinkageHelperTraits { static Register ReturnValueReg() { return r0; } static Register ReturnValue2Reg() { return r1; } static Register JSCallFunctionReg() { return r1; } @@ -33,33 +33,32 @@ struct LinkageHelperTraits { }; +typedef LinkageHelper LH; + CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) { - return LinkageHelper::GetJSCallDescriptor( - zone, parameter_count); + return LH::GetJSCallDescriptor(zone, parameter_count); } CallDescriptor* Linkage::GetRuntimeCallDescriptor( Runtime::FunctionId function, int parameter_count, Operator::Properties properties, Zone* zone) { - return LinkageHelper::GetRuntimeCallDescriptor( - zone, function, parameter_count, properties); + return LH::GetRuntimeCallDescriptor(zone, function, parameter_count, + properties); } CallDescriptor* Linkage::GetStubCallDescriptor( CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count, CallDescriptor::Flags flags, Zone* zone) { - return LinkageHelper::GetStubCallDescriptor( - zone, descriptor, stack_parameter_count, flags); + return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count, + flags); } -CallDescriptor* Linkage::GetSimplifiedCDescriptor( - Zone* zone, int num_params, MachineType return_type, - const MachineType* param_types) { - return LinkageHelper::GetSimplifiedCDescriptor( - zone, num_params, return_type, param_types); +CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone, + MachineSignature* sig) { + return LH::GetSimplifiedCDescriptor(zone, sig); } } // namespace compiler diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc index 16f5b19..d2fdf46 100644 --- a/src/compiler/arm64/code-generator-arm64.cc +++ b/src/compiler/arm64/code-generator-arm64.cc @@ -149,9 +149,15 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { break; } case kArchCallJSFunction: { - // TODO(jarin) The load of the context should be separated from the call. Register func = i.InputRegister(0); - __ Ldr(cp, FieldMemOperand(func, JSFunction::kContextOffset)); + if (FLAG_debug_code) { + // Check the function's context matches the context argument. + UseScratchRegisterScope scope(masm()); + Register temp = scope.AcquireX(); + __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); + __ cmp(cp, temp); + __ Assert(eq, kWrongFunctionContext); + } __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); __ Call(x10); AddSafepointAndDeopt(instr); @@ -701,8 +707,9 @@ void CodeGenerator::AssembleReturn() { } else { __ Mov(jssp, fp); __ Pop(fp, lr); - int pop_count = - descriptor->IsJSFunctionCall() ? descriptor->ParameterCount() : 0; + int pop_count = descriptor->IsJSFunctionCall() + ? static_cast(descriptor->JSParameterCount()) + : 0; __ Drop(pop_count); __ Ret(); } diff --git a/src/compiler/arm64/linkage-arm64.cc b/src/compiler/arm64/linkage-arm64.cc index 5729a71..5a61a71 100644 --- a/src/compiler/arm64/linkage-arm64.cc +++ b/src/compiler/arm64/linkage-arm64.cc @@ -14,7 +14,7 @@ namespace v8 { namespace internal { namespace compiler { -struct LinkageHelperTraits { +struct Arm64LinkageHelperTraits { static Register ReturnValueReg() { return x0; } static Register ReturnValue2Reg() { return x1; } static Register JSCallFunctionReg() { return x1; } @@ -33,33 +33,32 @@ struct LinkageHelperTraits { }; +typedef LinkageHelper LH; + CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) { - return LinkageHelper::GetJSCallDescriptor( - zone, parameter_count); + return LH::GetJSCallDescriptor(zone, parameter_count); } CallDescriptor* Linkage::GetRuntimeCallDescriptor( Runtime::FunctionId function, int parameter_count, Operator::Properties properties, Zone* zone) { - return LinkageHelper::GetRuntimeCallDescriptor( - zone, function, parameter_count, properties); + return LH::GetRuntimeCallDescriptor(zone, function, parameter_count, + properties); } CallDescriptor* Linkage::GetStubCallDescriptor( CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count, CallDescriptor::Flags flags, Zone* zone) { - return LinkageHelper::GetStubCallDescriptor( - zone, descriptor, stack_parameter_count, flags); + return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count, + flags); } -CallDescriptor* Linkage::GetSimplifiedCDescriptor( - Zone* zone, int num_params, MachineType return_type, - const MachineType* param_types) { - return LinkageHelper::GetSimplifiedCDescriptor( - zone, num_params, return_type, param_types); +CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone, + MachineSignature* sig) { + return LH::GetSimplifiedCDescriptor(zone, sig); } } // namespace compiler diff --git a/src/compiler/common-operator.h b/src/compiler/common-operator.h index 5318fd9..aa1aac7 100644 --- a/src/compiler/common-operator.h +++ b/src/compiler/common-operator.h @@ -35,11 +35,14 @@ class ControlOperator FINAL : public Operator1 { class CallOperator FINAL : public Operator1 { public: + // TODO(titzer): Operator still uses int, whereas CallDescriptor uses size_t. CallOperator(CallDescriptor* descriptor, const char* mnemonic) : Operator1( IrOpcode::kCall, descriptor->properties(), - descriptor->InputCount() + descriptor->FrameStateCount(), - descriptor->ReturnCount(), mnemonic, descriptor) {} + static_cast(descriptor->InputCount() + + descriptor->FrameStateCount()), + static_cast(descriptor->ReturnCount()), mnemonic, descriptor) { + } virtual OStream& PrintParameter(OStream& os) const OVERRIDE { // NOLINT return os << "[" << *parameter() << "]"; diff --git a/src/compiler/graph.cc b/src/compiler/graph.cc index 42f632f..f49ce34 100644 --- a/src/compiler/graph.cc +++ b/src/compiler/graph.cc @@ -22,7 +22,7 @@ Graph::Graph(Zone* zone) : GenericGraph(zone), decorators_(zone) {} Node* Graph::NewNode(Operator* op, int input_count, Node** inputs) { - DCHECK(op->InputCount() <= input_count); + DCHECK_LE(op->InputCount(), input_count); Node* result = Node::New(this, input_count, inputs); result->Initialize(op); for (ZoneVector::iterator i = decorators_.begin(); diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc index c05c6ea..54eb27e 100644 --- a/src/compiler/ia32/code-generator-ia32.cc +++ b/src/compiler/ia32/code-generator-ia32.cc @@ -132,9 +132,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { break; } case kArchCallJSFunction: { - // TODO(jarin) The load of the context should be separated from the call. Register func = i.InputRegister(0); - __ mov(esi, FieldOperand(func, JSFunction::kContextOffset)); + if (FLAG_debug_code) { + // Check the function's context matches the context argument. + __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); + __ Assert(equal, kWrongFunctionContext); + } __ call(FieldOperand(func, JSFunction::kCodeEntryOffset)); AddSafepointAndDeopt(instr); break; @@ -789,8 +792,9 @@ void CodeGenerator::AssembleReturn() { } else { __ mov(esp, ebp); // Move stack pointer back to frame pointer. __ pop(ebp); // Pop caller's frame pointer. - int pop_count = - descriptor->IsJSFunctionCall() ? descriptor->ParameterCount() : 0; + int pop_count = descriptor->IsJSFunctionCall() + ? static_cast(descriptor->JSParameterCount()) + : 0; __ ret(pop_count * kPointerSize); } } diff --git a/src/compiler/ia32/linkage-ia32.cc b/src/compiler/ia32/linkage-ia32.cc index 01bb6cc..e4b554d 100644 --- a/src/compiler/ia32/linkage-ia32.cc +++ b/src/compiler/ia32/linkage-ia32.cc @@ -14,7 +14,7 @@ namespace v8 { namespace internal { namespace compiler { -struct LinkageHelperTraits { +struct IA32LinkageHelperTraits { static Register ReturnValueReg() { return eax; } static Register ReturnValue2Reg() { return edx; } static Register JSCallFunctionReg() { return edi; } @@ -28,34 +28,32 @@ struct LinkageHelperTraits { static int CRegisterParametersLength() { return 0; } }; +typedef LinkageHelper LH; CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) { - return LinkageHelper::GetJSCallDescriptor( - zone, parameter_count); + return LH::GetJSCallDescriptor(zone, parameter_count); } CallDescriptor* Linkage::GetRuntimeCallDescriptor( Runtime::FunctionId function, int parameter_count, Operator::Properties properties, Zone* zone) { - return LinkageHelper::GetRuntimeCallDescriptor( - zone, function, parameter_count, properties); + return LH::GetRuntimeCallDescriptor(zone, function, parameter_count, + properties); } CallDescriptor* Linkage::GetStubCallDescriptor( CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count, CallDescriptor::Flags flags, Zone* zone) { - return LinkageHelper::GetStubCallDescriptor( - zone, descriptor, stack_parameter_count, flags); + return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count, + flags); } -CallDescriptor* Linkage::GetSimplifiedCDescriptor( - Zone* zone, int num_params, MachineType return_type, - const MachineType* param_types) { - return LinkageHelper::GetSimplifiedCDescriptor( - zone, num_params, return_type, param_types); +CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone, + MachineSignature* sig) { + return LH::GetSimplifiedCDescriptor(zone, sig); } } // namespace compiler diff --git a/src/compiler/instruction-selector-impl.h b/src/compiler/instruction-selector-impl.h index 1b174f6..efe5d83 100644 --- a/src/compiler/instruction-selector-impl.h +++ b/src/compiler/instruction-selector-impl.h @@ -48,8 +48,9 @@ class OperandGenerator { return ConstantOperand::Create(node->id(), zone()); } - InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location) { - return Define(node, ToUnallocatedOperand(location)); + InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location, + MachineType type) { + return Define(node, ToUnallocatedOperand(location, type)); } InstructionOperand* Use(Node* node) { @@ -94,8 +95,9 @@ class OperandGenerator { return ImmediateOperand::Create(index, zone()); } - InstructionOperand* UseLocation(Node* node, LinkageLocation location) { - return Use(node, ToUnallocatedOperand(location)); + InstructionOperand* UseLocation(Node* node, LinkageLocation location, + MachineType type) { + return Use(node, ToUnallocatedOperand(location, type)); } InstructionOperand* TempRegister() { @@ -174,7 +176,8 @@ class OperandGenerator { return operand; } - UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location) { + UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location, + MachineType type) { if (location.location_ == LinkageLocation::ANY_REGISTER) { return new (zone()) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER); @@ -183,7 +186,7 @@ class OperandGenerator { return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_SLOT, location.location_); } - if (RepresentationOf(location.rep_) == kRepFloat64) { + if (RepresentationOf(type) == kRepFloat64) { return new (zone()) UnallocatedOperand( UnallocatedOperand::FIXED_DOUBLE_REGISTER, location.location_); } @@ -338,11 +341,11 @@ struct CallBuffer { InstructionOperandVector instruction_args; NodeVector pushed_nodes; - int input_count() const { return descriptor->InputCount(); } + size_t input_count() const { return descriptor->InputCount(); } - int frame_state_count() const { return descriptor->FrameStateCount(); } + size_t frame_state_count() const { return descriptor->FrameStateCount(); } - int frame_state_value_count() const { + size_t frame_state_value_count() const { return (frame_state_descriptor == NULL) ? 0 : (frame_state_descriptor->size() + 1); diff --git a/src/compiler/instruction-selector-unittest.cc b/src/compiler/instruction-selector-unittest.cc index 36951a4..5a70d67 100644 --- a/src/compiler/instruction-selector-unittest.cc +++ b/src/compiler/instruction-selector-unittest.cc @@ -284,12 +284,14 @@ TARGET_TEST_F(InstructionSelectorTest, ValueEffect) { // ----------------------------------------------------------------------------- // Calls with deoptimization. TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) { - StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged); + StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, + kMachAnyTagged); BailoutId bailout_id(42); Node* function_node = m.Parameter(0); Node* receiver = m.Parameter(1); + Node* context = m.Parameter(2); Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(1)); Node* locals = m.NewNode(m.common()->StateValues(0)); @@ -298,7 +300,7 @@ TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) { Node* state_node = m.NewNode(m.common()->FrameState(bailout_id, kPushOutput), parameters, locals, stack, context_dummy); - Node* call = m.CallJS0(function_node, receiver, state_node); + Node* call = m.CallJS0(function_node, receiver, context, state_node); m.Return(call); Stream s = m.Build(kAllExceptNopInstructions); diff --git a/src/compiler/instruction-selector-unittest.h b/src/compiler/instruction-selector-unittest.h index 3f6f252..476733c 100644 --- a/src/compiler/instruction-selector-unittest.h +++ b/src/compiler/instruction-selector-unittest.h @@ -36,28 +36,28 @@ class InstructionSelectorTest : public CompilerTest { public: StreamBuilder(InstructionSelectorTest* test, MachineType return_type) : RawMachineAssembler(new (test->zone()) Graph(test->zone()), - CallDescriptorBuilder(test->zone(), return_type)), + MakeMachineSignature(test->zone(), return_type)), test_(test) {} StreamBuilder(InstructionSelectorTest* test, MachineType return_type, MachineType parameter0_type) - : RawMachineAssembler(new (test->zone()) Graph(test->zone()), - CallDescriptorBuilder(test->zone(), return_type, - parameter0_type)), + : RawMachineAssembler( + new (test->zone()) Graph(test->zone()), + MakeMachineSignature(test->zone(), return_type, parameter0_type)), test_(test) {} StreamBuilder(InstructionSelectorTest* test, MachineType return_type, MachineType parameter0_type, MachineType parameter1_type) : RawMachineAssembler( new (test->zone()) Graph(test->zone()), - CallDescriptorBuilder(test->zone(), return_type, parameter0_type, - parameter1_type)), + MakeMachineSignature(test->zone(), return_type, parameter0_type, + parameter1_type)), test_(test) {} StreamBuilder(InstructionSelectorTest* test, MachineType return_type, MachineType parameter0_type, MachineType parameter1_type, MachineType parameter2_type) : RawMachineAssembler( new (test->zone()) Graph(test->zone()), - CallDescriptorBuilder(test->zone(), return_type, parameter0_type, - parameter1_type, parameter2_type)), + MakeMachineSignature(test->zone(), return_type, parameter0_type, + parameter1_type, parameter2_type)), test_(test) {} Stream Build(CpuFeature feature) { @@ -73,38 +73,41 @@ class InstructionSelectorTest : public CompilerTest { StreamBuilderMode mode = kTargetInstructions); private: - MachineCallDescriptorBuilder* CallDescriptorBuilder( - Zone* zone, MachineType return_type) { - return new (zone) MachineCallDescriptorBuilder(return_type, 0, NULL); - } - - MachineCallDescriptorBuilder* CallDescriptorBuilder( - Zone* zone, MachineType return_type, MachineType parameter0_type) { - MachineType* parameter_types = zone->NewArray(1); - parameter_types[0] = parameter0_type; - return new (zone) - MachineCallDescriptorBuilder(return_type, 1, parameter_types); - } - - MachineCallDescriptorBuilder* CallDescriptorBuilder( - Zone* zone, MachineType return_type, MachineType parameter0_type, - MachineType parameter1_type) { - MachineType* parameter_types = zone->NewArray(2); - parameter_types[0] = parameter0_type; - parameter_types[1] = parameter1_type; - return new (zone) - MachineCallDescriptorBuilder(return_type, 2, parameter_types); - } - - MachineCallDescriptorBuilder* CallDescriptorBuilder( - Zone* zone, MachineType return_type, MachineType parameter0_type, - MachineType parameter1_type, MachineType parameter2_type) { - MachineType* parameter_types = zone->NewArray(3); - parameter_types[0] = parameter0_type; - parameter_types[1] = parameter1_type; - parameter_types[2] = parameter2_type; - return new (zone) - MachineCallDescriptorBuilder(return_type, 3, parameter_types); + MachineSignature* MakeMachineSignature(Zone* zone, + MachineType return_type) { + MachineSignature::Builder builder(zone, 1, 0); + builder.AddReturn(return_type); + return builder.Build(); + } + + MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, + MachineType parameter0_type) { + MachineSignature::Builder builder(zone, 1, 1); + builder.AddReturn(return_type); + builder.AddParam(parameter0_type); + return builder.Build(); + } + + MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, + MachineType parameter0_type, + MachineType parameter1_type) { + MachineSignature::Builder builder(zone, 1, 2); + builder.AddReturn(return_type); + builder.AddParam(parameter0_type); + builder.AddParam(parameter1_type); + return builder.Build(); + } + + MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, + MachineType parameter0_type, + MachineType parameter1_type, + MachineType parameter2_type) { + MachineSignature::Builder builder(zone, 1, 3); + builder.AddReturn(return_type); + builder.AddParam(parameter0_type); + builder.AddParam(parameter1_type); + builder.AddParam(parameter2_type); + return builder.Build(); } private: diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index a530824..fea6141 100644 --- a/src/compiler/instruction-selector.cc +++ b/src/compiler/instruction-selector.cc @@ -296,10 +296,12 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, for (size_t i = 0; i < buffer->output_nodes.size(); i++) { if (buffer->output_nodes[i] != NULL) { Node* output = buffer->output_nodes[i]; + MachineType type = + buffer->descriptor->GetReturnType(static_cast(i)); LinkageLocation location = buffer->descriptor->GetReturnLocation(static_cast(i)); - MarkAsRepresentation(location.representation(), output); - buffer->outputs.push_back(g.DefineAsLocation(output, location)); + MarkAsRepresentation(type, output); + buffer->outputs.push_back(g.DefineAsLocation(output, location, type)); } } } @@ -323,7 +325,8 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, break; case CallDescriptor::kCallJSFunction: buffer->instruction_args.push_back( - g.UseLocation(callee, buffer->descriptor->GetInputLocation(0))); + g.UseLocation(callee, buffer->descriptor->GetInputLocation(0), + buffer->descriptor->GetInputType(0))); break; } DCHECK_EQ(1, buffer->instruction_args.size()); @@ -337,14 +340,15 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor); buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt())); - Node* frame_state = call->InputAt(buffer->descriptor->InputCount()); + Node* frame_state = + call->InputAt(static_cast(buffer->descriptor->InputCount())); AddFrameStateInputs(frame_state, &buffer->instruction_args, buffer->frame_state_descriptor); } - DCHECK_EQ(1 + buffer->frame_state_value_count(), - buffer->instruction_args.size()); + DCHECK(1 + buffer->frame_state_value_count() == + buffer->instruction_args.size()); - int input_count = buffer->input_count(); + size_t input_count = static_cast(buffer->input_count()); // Split the arguments into pushed_nodes and instruction_args. Pushed // arguments require an explicit push instruction before the call and do @@ -352,13 +356,14 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, // as an InstructionOperand argument to the call. InputIter iter(call->inputs().begin()); int pushed_count = 0; - for (int index = 0; index < input_count; ++iter, ++index) { + for (size_t index = 0; index < input_count; ++iter, ++index) { DCHECK(iter != call->inputs().end()); - DCHECK(index == iter.index()); + DCHECK(index == static_cast(iter.index())); DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); if (index == 0) continue; // The first argument (callee) is already done. InstructionOperand* op = - g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index)); + g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index), + buffer->descriptor->GetInputType(index)); if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; if (static_cast(stack_index) >= buffer->pushed_nodes.size()) { @@ -482,9 +487,8 @@ void InstructionSelector::VisitNode(Node* node) { case IrOpcode::kFinish: return MarkAsReference(node), VisitFinish(node); case IrOpcode::kParameter: { - LinkageLocation location = - linkage()->GetParameterLocation(OpParameter(node)); - MarkAsRepresentation(location.representation(), node); + MachineType type = linkage()->GetParameterType(OpParameter(node)); + MarkAsRepresentation(type, node); return VisitParameter(node); } case IrOpcode::kPhi: @@ -820,8 +824,10 @@ void InstructionSelector::VisitFinish(Node* node) { void InstructionSelector::VisitParameter(Node* node) { OperandGenerator g(this); - Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetParameterLocation( - OpParameter(node)))); + int index = OpParameter(node); + Emit(kArchNop, + g.DefineAsLocation(node, linkage()->GetParameterLocation(index), + linkage()->GetParameterType(index))); } @@ -985,7 +991,8 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, void InstructionSelector::VisitReturn(Node* value) { OperandGenerator g(this); if (value != NULL) { - Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation())); + Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation(), + linkage()->GetReturnType())); } else { Emit(kArchRet, NULL); } diff --git a/src/compiler/linkage-impl.h b/src/compiler/linkage-impl.h index e2b7df0..e35f47c 100644 --- a/src/compiler/linkage-impl.h +++ b/src/compiler/linkage-impl.h @@ -9,194 +9,215 @@ namespace v8 { namespace internal { namespace compiler { +// TODO(titzer): replace uses of int with size_t in LinkageHelper. +template class LinkageHelper { public: - static LinkageLocation TaggedStackSlot(int index) { - DCHECK(index < 0); - return LinkageLocation(kMachAnyTagged, index); - } - - static LinkageLocation TaggedRegisterLocation(Register reg) { - return LinkageLocation(kMachAnyTagged, Register::ToAllocationIndex(reg)); - } - - static inline LinkageLocation WordRegisterLocation(Register reg) { - return LinkageLocation(kMachPtr, Register::ToAllocationIndex(reg)); - } + static const RegList kNoCalleeSaved = 0; - static LinkageLocation UnconstrainedRegister(MachineType rep) { - return LinkageLocation(rep, LinkageLocation::ANY_REGISTER); + static void AddReturnLocations(LocationSignature::Builder* locations) { + DCHECK(locations->return_count_ <= 2); + if (locations->return_count_ > 0) { + locations->AddReturn(regloc(LinkageTraits::ReturnValueReg())); + } + if (locations->return_count_ > 1) { + locations->AddReturn(regloc(LinkageTraits::ReturnValue2Reg())); + } } - static const RegList kNoCalleeSaved = 0; - // TODO(turbofan): cache call descriptors for JSFunction calls. - template - static CallDescriptor* GetJSCallDescriptor(Zone* zone, int parameter_count) { - const int jsfunction_count = 1; - const int context_count = 1; - int input_count = jsfunction_count + parameter_count + context_count; - - const int return_count = 1; - LinkageLocation* locations = - zone->NewArray(return_count + input_count); - - int index = 0; - locations[index++] = - TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); - locations[index++] = - TaggedRegisterLocation(LinkageTraits::JSCallFunctionReg()); - - for (int i = 0; i < parameter_count; i++) { - // All parameters to JS calls go on the stack. - int spill_slot_index = i - parameter_count; - locations[index++] = TaggedStackSlot(spill_slot_index); + static CallDescriptor* GetJSCallDescriptor(Zone* zone, + int js_parameter_count) { + const size_t return_count = 1; + const size_t context_count = 1; + const size_t parameter_count = js_parameter_count + context_count; + + LocationSignature::Builder locations(zone, return_count, parameter_count); + MachineSignature::Builder types(zone, return_count, parameter_count); + + // Add returns. + AddReturnLocations(&locations); + for (size_t i = 0; i < return_count; i++) { + types.AddReturn(kMachAnyTagged); } - locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); - // TODO(titzer): refactor TurboFan graph to consider context a value input. - return new (zone) - CallDescriptor(CallDescriptor::kCallJSFunction, // kind - return_count, // return_count - parameter_count, // parameter_count - input_count - context_count, // input_count - locations, // locations - Operator::kNoProperties, // properties - kNoCalleeSaved, // callee-saved registers - CallDescriptor::kNeedsFrameState); // flags + // All parameters to JS calls go on the stack. + for (int i = 0; i < js_parameter_count; i++) { + int spill_slot_index = i - js_parameter_count; + locations.AddParam(stackloc(spill_slot_index)); + types.AddParam(kMachAnyTagged); + } + // Add context. + locations.AddParam(regloc(LinkageTraits::ContextReg())); + types.AddParam(kMachAnyTagged); + + // The target for JS function calls is the JSFunction object. + MachineType target_type = kMachAnyTagged; + LinkageLocation target_loc = regloc(LinkageTraits::JSCallFunctionReg()); + return new (zone) CallDescriptor(CallDescriptor::kCallJSFunction, // kind + target_type, // target MachineType + target_loc, // target location + types.Build(), // machine_sig + locations.Build(), // location_sig + js_parameter_count, // js_parameter_count + Operator::kNoProperties, // properties + kNoCalleeSaved, // callee-saved + CallDescriptor::kNeedsFrameState, // flags + "js-call"); } // TODO(turbofan): cache call descriptors for runtime calls. - template static CallDescriptor* GetRuntimeCallDescriptor( - Zone* zone, Runtime::FunctionId function_id, int parameter_count, + Zone* zone, Runtime::FunctionId function_id, int js_parameter_count, Operator::Properties properties) { - const int code_count = 1; - const int function_count = 1; - const int num_args_count = 1; - const int context_count = 1; - const int input_count = code_count + parameter_count + function_count + - num_args_count + context_count; + const size_t function_count = 1; + const size_t num_args_count = 1; + const size_t context_count = 1; + const size_t parameter_count = function_count + + static_cast(js_parameter_count) + + num_args_count + context_count; const Runtime::Function* function = Runtime::FunctionForId(function_id); - const int return_count = function->result_size; - LinkageLocation* locations = - zone->NewArray(return_count + input_count); - - int index = 0; - if (return_count > 0) { - locations[index++] = - TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); - } - if (return_count > 1) { - locations[index++] = - TaggedRegisterLocation(LinkageTraits::ReturnValue2Reg()); - } + const size_t return_count = static_cast(function->result_size); - DCHECK_LE(return_count, 2); + LocationSignature::Builder locations(zone, return_count, parameter_count); + MachineSignature::Builder types(zone, return_count, parameter_count); - locations[index++] = UnconstrainedRegister(kMachAnyTagged); // CEntryStub + // Add returns. + AddReturnLocations(&locations); + for (size_t i = 0; i < return_count; i++) { + types.AddReturn(kMachAnyTagged); + } - for (int i = 0; i < parameter_count; i++) { - // All parameters to runtime calls go on the stack. - int spill_slot_index = i - parameter_count; - locations[index++] = TaggedStackSlot(spill_slot_index); + // All parameters to the runtime call go on the stack. + for (int i = 0; i < js_parameter_count; i++) { + locations.AddParam(stackloc(i - js_parameter_count)); + types.AddParam(kMachAnyTagged); } - locations[index++] = - TaggedRegisterLocation(LinkageTraits::RuntimeCallFunctionReg()); - locations[index++] = - WordRegisterLocation(LinkageTraits::RuntimeCallArgCountReg()); - locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); + // Add runtime function itself. + locations.AddParam(regloc(LinkageTraits::RuntimeCallFunctionReg())); + types.AddParam(kMachAnyTagged); + + // Add runtime call argument count. + locations.AddParam(regloc(LinkageTraits::RuntimeCallArgCountReg())); + types.AddParam(kMachPtr); + + // Add context. + locations.AddParam(regloc(LinkageTraits::ContextReg())); + types.AddParam(kMachAnyTagged); CallDescriptor::Flags flags = Linkage::NeedsFrameState(function_id) ? CallDescriptor::kNeedsFrameState : CallDescriptor::kNoFlags; - // TODO(titzer): refactor TurboFan graph to consider context a value input. + // The target for runtime calls is a code object. + MachineType target_type = kMachAnyTagged; + LinkageLocation target_loc = LinkageLocation::AnyRegister(); return new (zone) CallDescriptor(CallDescriptor::kCallCodeObject, // kind - return_count, // return_count - parameter_count, // parameter_count - input_count, // input_count - locations, // locations - properties, // properties - kNoCalleeSaved, // callee-saved registers - flags, // flags - function->name); + target_type, // target MachineType + target_loc, // target location + types.Build(), // machine_sig + locations.Build(), // location_sig + js_parameter_count, // js_parameter_count + properties, // properties + kNoCalleeSaved, // callee-saved + flags, // flags + function->name); // debug name } // TODO(turbofan): cache call descriptors for code stub calls. - template static CallDescriptor* GetStubCallDescriptor( Zone* zone, CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count, CallDescriptor::Flags flags) { - int register_parameter_count = descriptor->GetEnvironmentParameterCount(); - int parameter_count = register_parameter_count + stack_parameter_count; - const int code_count = 1; + const int register_parameter_count = + descriptor->GetEnvironmentParameterCount(); + const int js_parameter_count = + register_parameter_count + stack_parameter_count; const int context_count = 1; - int input_count = code_count + parameter_count + context_count; + const size_t return_count = 1; + const size_t parameter_count = + static_cast(js_parameter_count + context_count); - const int return_count = 1; - LinkageLocation* locations = - zone->NewArray(return_count + input_count); + LocationSignature::Builder locations(zone, return_count, parameter_count); + MachineSignature::Builder types(zone, return_count, parameter_count); - int index = 0; - locations[index++] = - TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); - locations[index++] = UnconstrainedRegister(kMachAnyTagged); // code - for (int i = 0; i < parameter_count; i++) { + // Add return location. + AddReturnLocations(&locations); + types.AddReturn(kMachAnyTagged); + + // Add parameters in registers and on the stack. + for (int i = 0; i < js_parameter_count; i++) { if (i < register_parameter_count) { - // The first parameters to code stub calls go in registers. + // The first parameters go in registers. Register reg = descriptor->GetEnvironmentParameterRegister(i); - locations[index++] = TaggedRegisterLocation(reg); + locations.AddParam(regloc(reg)); } else { // The rest of the parameters go on the stack. int stack_slot = i - register_parameter_count - stack_parameter_count; - locations[index++] = TaggedStackSlot(stack_slot); + locations.AddParam(stackloc(stack_slot)); } + types.AddParam(kMachAnyTagged); } - locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); + // Add context. + locations.AddParam(regloc(LinkageTraits::ContextReg())); + types.AddParam(kMachAnyTagged); - // TODO(titzer): refactor TurboFan graph to consider context a value input. + // The target for stub calls is a code object. + MachineType target_type = kMachAnyTagged; + LinkageLocation target_loc = LinkageLocation::AnyRegister(); return new (zone) CallDescriptor(CallDescriptor::kCallCodeObject, // kind - return_count, // return_count - parameter_count, // parameter_count - input_count, // input_count - locations, // locations + target_type, // target MachineType + target_loc, // target location + types.Build(), // machine_sig + locations.Build(), // location_sig + js_parameter_count, // js_parameter_count Operator::kNoProperties, // properties kNoCalleeSaved, // callee-saved registers flags, // flags CodeStub::MajorName(descriptor->MajorKey(), false)); } + static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone, + MachineSignature* msig) { + LocationSignature::Builder locations(zone, msig->return_count(), + msig->parameter_count()); + // Add return location(s). + AddReturnLocations(&locations); - template - static CallDescriptor* GetSimplifiedCDescriptor( - Zone* zone, int num_params, MachineType return_type, - const MachineType* param_types) { - LinkageLocation* locations = - zone->NewArray(num_params + 2); - int index = 0; - locations[index++] = - TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); - locations[index++] = LinkageHelper::UnconstrainedRegister(kMachPtr); - // TODO(dcarney): test with lots of parameters. - int i = 0; - for (; i < LinkageTraits::CRegisterParametersLength() && i < num_params; - i++) { - locations[index++] = LinkageLocation( - param_types[i], - Register::ToAllocationIndex(LinkageTraits::CRegisterParameter(i))); - } - for (; i < num_params; i++) { - locations[index++] = LinkageLocation(param_types[i], -1 - i); + // Add register and/or stack parameter(s). + const int parameter_count = static_cast(msig->parameter_count()); + for (int i = 0; i < parameter_count; i++) { + if (i < LinkageTraits::CRegisterParametersLength()) { + locations.AddParam(regloc(LinkageTraits::CRegisterParameter(i))); + } else { + locations.AddParam(stackloc(-1 - i)); + } } - return new (zone) CallDescriptor( - CallDescriptor::kCallAddress, 1, num_params, num_params + 1, locations, - Operator::kNoProperties, LinkageTraits::CCalleeSaveRegisters(), - CallDescriptor::kNoFlags); // TODO(jarin) should deoptimize! + + // The target for C calls is always an address (i.e. machine pointer). + MachineType target_type = kMachPtr; + LinkageLocation target_loc = LinkageLocation::AnyRegister(); + return new (zone) CallDescriptor(CallDescriptor::kCallAddress, // kind + target_type, // target MachineType + target_loc, // target location + msig, // machine_sig + locations.Build(), // location_sig + 0, // js_parameter_count + Operator::kNoProperties, // properties + LinkageTraits::CCalleeSaveRegisters(), + CallDescriptor::kNoFlags, "c-call"); + } + + static LinkageLocation regloc(Register reg) { + return LinkageLocation(Register::ToAllocationIndex(reg)); + } + + static LinkageLocation stackloc(int i) { + DCHECK_LT(i, 0); + return LinkageLocation(i); } }; } // namespace compiler diff --git a/src/compiler/linkage.cc b/src/compiler/linkage.cc index f2213f5..adeeccb 100644 --- a/src/compiler/linkage.cc +++ b/src/compiler/linkage.cc @@ -34,7 +34,7 @@ OStream& operator<<(OStream& os, const CallDescriptor::Kind& k) { OStream& operator<<(OStream& os, const CallDescriptor& d) { // TODO(svenpanne) Output properties etc. and be less cryptic. return os << d.kind() << ":" << d.debug_name() << ":r" << d.ReturnCount() - << "p" << d.ParameterCount() << "i" << d.InputCount() << "f" + << "j" << d.JSParameterCount() << "i" << d.InputCount() << "f" << d.FrameStateCount(); } diff --git a/src/compiler/linkage.h b/src/compiler/linkage.h index f0f14e3..e742af8 100644 --- a/src/compiler/linkage.h +++ b/src/compiler/linkage.h @@ -18,29 +18,32 @@ namespace internal { namespace compiler { // Describes the location for a parameter or a return value to a call. -// TODO(titzer): replace with Radium locations when they are ready. class LinkageLocation { public: - LinkageLocation(MachineType rep, int location) - : rep_(rep), location_(location) {} - - inline MachineType representation() const { return rep_; } + explicit LinkageLocation(int location) : location_(location) {} static const int16_t ANY_REGISTER = 32767; + static LinkageLocation AnyRegister() { return LinkageLocation(ANY_REGISTER); } + private: friend class CallDescriptor; friend class OperandGenerator; - MachineType rep_; int16_t location_; // >= 0 implies register, otherwise stack slot. }; +typedef Signature LocationSignature; +// Describes a call to various parts of the compiler. Every call has the notion +// of a "target", which is the first input to the call. class CallDescriptor FINAL : public ZoneObject { public: - // Describes whether the first parameter is a code object, a JSFunction, - // or an address--all of which require different machine sequences to call. - enum Kind { kCallCodeObject, kCallJSFunction, kCallAddress }; + // Describes the kind of this call, which determines the target. + enum Kind { + kCallCodeObject, // target is a Code object + kCallJSFunction, // target is a JSFunction object + kCallAddress // target is a machine pointer + }; enum Flag { // TODO(jarin) kLazyDeoptimization and kNeedsFrameState should be unified. @@ -52,56 +55,74 @@ class CallDescriptor FINAL : public ZoneObject { }; typedef base::Flags Flags; - CallDescriptor(Kind kind, int8_t return_count, int16_t parameter_count, - int16_t input_count, LinkageLocation* locations, - Operator::Properties properties, + CallDescriptor(Kind kind, MachineType target_type, LinkageLocation target_loc, + MachineSignature* machine_sig, LocationSignature* location_sig, + size_t js_param_count, Operator::Properties properties, RegList callee_saved_registers, Flags flags, const char* debug_name = "") : kind_(kind), - return_count_(return_count), - parameter_count_(parameter_count), - input_count_(input_count), - locations_(locations), + target_type_(target_type), + target_loc_(target_loc), + machine_sig_(machine_sig), + location_sig_(location_sig), + js_param_count_(js_param_count), properties_(properties), callee_saved_registers_(callee_saved_registers), flags_(flags), - debug_name_(debug_name) {} + debug_name_(debug_name) { + DCHECK(machine_sig->return_count() == location_sig->return_count()); + DCHECK(machine_sig->parameter_count() == location_sig->parameter_count()); + } + // Returns the kind of this call. Kind kind() const { return kind_; } // Returns {true} if this descriptor is a call to a JSFunction. bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; } - // The number of return values from this call, usually 0 or 1. - int ReturnCount() const { return return_count_; } + // The number of return values from this call. + size_t ReturnCount() const { return machine_sig_->return_count(); } - // The number of JavaScript parameters to this call, including receiver, - // but not the context. - int ParameterCount() const { return parameter_count_; } + // The number of JavaScript parameters to this call, including the receiver + // object. + size_t JSParameterCount() const { return js_param_count_; } - int InputCount() const { return input_count_; } + // The total number of inputs to this call, which includes the target, + // receiver, context, etc. + // TODO(titzer): this should input the framestate input too. + size_t InputCount() const { return 1 + machine_sig_->parameter_count(); } - int FrameStateCount() const { return NeedsFrameState() ? 1 : 0; } + size_t FrameStateCount() const { return NeedsFrameState() ? 1 : 0; } Flags flags() const { return flags_; } bool NeedsFrameState() const { return flags() & kNeedsFrameState; } - LinkageLocation GetReturnLocation(int index) { - DCHECK(index < return_count_); - return locations_[0 + index]; // return locations start at 0. + LinkageLocation GetReturnLocation(size_t index) const { + return location_sig_->GetReturn(index); } - LinkageLocation GetInputLocation(int index) { - DCHECK(index < input_count_ + 1); // input_count + 1 is the context. - return locations_[return_count_ + index]; // inputs start after returns. + LinkageLocation GetInputLocation(size_t index) const { + if (index == 0) return target_loc_; + return location_sig_->GetParam(index - 1); + } + + const MachineSignature* GetMachineSignature() const { return machine_sig_; } + + MachineType GetReturnType(size_t index) const { + return machine_sig_->GetReturn(index); + } + + MachineType GetInputType(size_t index) const { + if (index == 0) return target_type_; + return machine_sig_->GetParam(index - 1); } // Operator properties describe how this call can be optimized, if at all. Operator::Properties properties() const { return properties_; } // Get the callee-saved registers, if any, across this call. - RegList CalleeSavedRegisters() { return callee_saved_registers_; } + RegList CalleeSavedRegisters() const { return callee_saved_registers_; } const char* debug_name() const { return debug_name_; } @@ -109,10 +130,11 @@ class CallDescriptor FINAL : public ZoneObject { friend class Linkage; Kind kind_; - int8_t return_count_; - int16_t parameter_count_; - int16_t input_count_; - LinkageLocation* locations_; + MachineType target_type_; + LinkageLocation target_loc_; + MachineSignature* machine_sig_; + LocationSignature* location_sig_; + size_t js_param_count_; Operator::Properties properties_; RegList callee_saved_registers_; Flags flags_; @@ -166,13 +188,17 @@ class Linkage : public ZoneObject { // for the host platform. This simplified calling convention only supports // integers and pointers of one word size each, i.e. no floating point, // structs, pointers to members, etc. - static CallDescriptor* GetSimplifiedCDescriptor( - Zone* zone, int num_params, MachineType return_type, - const MachineType* param_types); + static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone, + MachineSignature* sig); // Get the location of an (incoming) parameter to this function. LinkageLocation GetParameterLocation(int index) { - return incoming_->GetInputLocation(index + 1); + return incoming_->GetInputLocation(index + 1); // + 1 to skip target. + } + + // Get the machine type of an (incoming) parameter to this function. + MachineType GetParameterType(int index) { + return incoming_->GetInputType(index + 1); // + 1 to skip target. } // Get the location where this function should place its return value. @@ -180,6 +206,9 @@ class Linkage : public ZoneObject { return incoming_->GetReturnLocation(0); } + // Get the machine type of this function's return value. + MachineType GetReturnType() { return incoming_->GetReturnType(0); } + // Get the frame offset for a given spill slot. The location depends on the // calling convention and the specific frame layout, and may thus be // architecture-specific. Negative spill slots indicate arguments on the diff --git a/src/compiler/machine-node-factory.h b/src/compiler/machine-node-factory.h index 1d5b7fe..7b2e5ff 100644 --- a/src/compiler/machine-node-factory.h +++ b/src/compiler/machine-node-factory.h @@ -20,32 +20,10 @@ namespace v8 { namespace internal { namespace compiler { -class MachineCallDescriptorBuilder : public ZoneObject { - public: - MachineCallDescriptorBuilder(MachineType return_type, int parameter_count, - const MachineType* parameter_types) - : return_type_(return_type), - parameter_count_(parameter_count), - parameter_types_(parameter_types) {} - - int parameter_count() const { return parameter_count_; } - const MachineType* parameter_types() const { return parameter_types_; } - - CallDescriptor* BuildCallDescriptor(Zone* zone) { - return Linkage::GetSimplifiedCDescriptor(zone, parameter_count_, - return_type_, parameter_types_); - } - - private: - const MachineType return_type_; - const int parameter_count_; - const MachineType* const parameter_types_; -}; - - #define ZONE() static_cast(this)->zone() #define COMMON() static_cast(this)->common() #define MACHINE() static_cast(this)->machine() +#define MACHINE_SIG() static_cast(this)->machine_sig() #define NEW_NODE_0(op) static_cast(this)->NewNode(op) #define NEW_NODE_1(op, a) static_cast(this)->NewNode(op, a) #define NEW_NODE_2(op, a, b) static_cast(this)->NewNode(op, a, b) @@ -369,8 +347,8 @@ class MachineNodeFactory { // Call to C. Node* CallC(Node* function_address, MachineType return_type, MachineType* arg_types, Node** args, int n_args) { - CallDescriptor* descriptor = Linkage::GetSimplifiedCDescriptor( - ZONE(), n_args, return_type, arg_types); + CallDescriptor* descriptor = + Linkage::GetSimplifiedCDescriptor(ZONE(), MACHINE_SIG()); Node** passed_args = static_cast(alloca((n_args + 1) * sizeof(args[0]))); passed_args[0] = function_address; diff --git a/src/compiler/machine-type.h b/src/compiler/machine-type.h index 22513d9..771350b 100644 --- a/src/compiler/machine-type.h +++ b/src/compiler/machine-type.h @@ -7,6 +7,7 @@ #include "src/base/bits.h" #include "src/globals.h" +#include "src/zone.h" namespace v8 { namespace internal { @@ -109,32 +110,71 @@ inline int ElementSizeOf(MachineType machine_type) { } } -// Describes the inputs and outputs of a function or call in terms of machine -// types. -class MachineSignature { +// Describes the inputs and outputs of a function or call. +template +class Signature : public ZoneObject { public: - MachineSignature(uint8_t return_count, uint16_t param_count, - MachineType* reps) - : return_count_(return_count), param_count_(param_count), reps_(reps) {} + Signature(size_t return_count, size_t parameter_count, T* reps) + : return_count_(return_count), + parameter_count_(parameter_count), + reps_(reps) {} - int GetReturnCount() const { return return_count_; } - int GetParamCount() const { return param_count_; } + size_t return_count() const { return return_count_; } + size_t parameter_count() const { return parameter_count_; } - MachineType GetParameterType(int index) const { - DCHECK(index >= 0 && index < param_count_); + T GetParam(size_t index) const { + DCHECK(index < parameter_count_); return reps_[return_count_ + index]; } - MachineType GetReturnType(int index = 0) const { - DCHECK(index >= 0 && index < return_count_); + T GetReturn(size_t index = 0) const { + DCHECK(index < return_count_); return reps_[index]; } + // For incrementally building signatures. + class Builder { + public: + Builder(Zone* zone, size_t return_count, size_t parameter_count) + : return_count_(return_count), + parameter_count_(parameter_count), + zone_(zone), + rcursor_(0), + pcursor_(0), + buffer_(zone->NewArray( + static_cast(return_count + parameter_count))) {} + + const size_t return_count_; + const size_t parameter_count_; + + void AddReturn(T val) { + DCHECK(rcursor_ < return_count_); + buffer_[rcursor_++] = val; + } + void AddParam(T val) { + DCHECK(pcursor_ < parameter_count_); + buffer_[return_count_ + pcursor_++] = val; + } + Signature* Build() { + DCHECK(rcursor_ == return_count_); + DCHECK(pcursor_ == parameter_count_); + return new (zone_) Signature(return_count_, parameter_count_, buffer_); + } + + private: + Zone* zone_; + size_t rcursor_; + size_t pcursor_; + T* buffer_; + }; + protected: - uint8_t return_count_; - uint16_t param_count_; - MachineType* reps_; + size_t return_count_; + size_t parameter_count_; + T* reps_; }; + +typedef Signature MachineSignature; } // namespace compiler } // namespace internal } // namespace v8 diff --git a/src/compiler/raw-machine-assembler.cc b/src/compiler/raw-machine-assembler.cc index 395c96e..329d8de 100644 --- a/src/compiler/raw-machine-assembler.cc +++ b/src/compiler/raw-machine-assembler.cc @@ -10,23 +10,27 @@ namespace v8 { namespace internal { namespace compiler { -RawMachineAssembler::RawMachineAssembler( - Graph* graph, MachineCallDescriptorBuilder* call_descriptor_builder, - MachineType word) +RawMachineAssembler::RawMachineAssembler(Graph* graph, + MachineSignature* machine_sig, + MachineType word) : GraphBuilder(graph), schedule_(new (zone()) Schedule(zone())), machine_(zone(), word), common_(zone()), - call_descriptor_builder_(call_descriptor_builder), + machine_sig_(machine_sig), + call_descriptor_( + Linkage::GetSimplifiedCDescriptor(graph->zone(), machine_sig)), parameters_(NULL), exit_label_(schedule()->end()), current_block_(schedule()->start()) { - Node* s = graph->NewNode(common_.Start(parameter_count())); + int param_count = static_cast(parameter_count()); + Node* s = graph->NewNode(common_.Start(param_count)); graph->SetStart(s); if (parameter_count() == 0) return; - parameters_ = zone()->NewArray(parameter_count()); - for (int i = 0; i < parameter_count(); ++i) { - parameters_[i] = NewNode(common()->Parameter(i), graph->start()); + parameters_ = zone()->NewArray(param_count); + for (size_t i = 0; i < parameter_count(); ++i) { + parameters_[i] = + NewNode(common()->Parameter(static_cast(i)), graph->start()); } } @@ -42,8 +46,8 @@ Schedule* RawMachineAssembler::Export() { } -Node* RawMachineAssembler::Parameter(int index) { - DCHECK(0 <= index && index < parameter_count()); +Node* RawMachineAssembler::Parameter(size_t index) { + DCHECK(index < parameter_count()); return parameters_[index]; } @@ -95,17 +99,18 @@ Node* RawMachineAssembler::CallFunctionStub0(Node* function, Node* receiver, Node* RawMachineAssembler::CallJS0(Node* function, Node* receiver, - Node* frame_state) { + Node* context, Node* frame_state) { CallDescriptor* descriptor = Linkage::GetJSCallDescriptor(1, zone()); Node* call = graph()->NewNode(common()->Call(descriptor), function, receiver, - frame_state); + context, frame_state); schedule()->AddNode(CurrentBlock(), call); return call; } Node* RawMachineAssembler::CallRuntime1(Runtime::FunctionId function, - Node* arg0, Node* frame_state) { + Node* arg0, Node* context, + Node* frame_state) { CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor( function, 1, Operator::kNoProperties, zone()); @@ -113,7 +118,6 @@ Node* RawMachineAssembler::CallRuntime1(Runtime::FunctionId function, Node* ref = NewNode( common()->ExternalConstant(ExternalReference(function, isolate()))); Node* arity = Int32Constant(1); - Node* context = Parameter(1); Node* call = graph()->NewNode(common()->Call(descriptor), centry, arg0, ref, arity, context, frame_state); diff --git a/src/compiler/raw-machine-assembler.h b/src/compiler/raw-machine-assembler.h index 04e0fee..5e08d40 100644 --- a/src/compiler/raw-machine-assembler.h +++ b/src/compiler/raw-machine-assembler.h @@ -45,8 +45,7 @@ class RawMachineAssembler : public GraphBuilder, DISALLOW_COPY_AND_ASSIGN(Label); }; - RawMachineAssembler(Graph* graph, - MachineCallDescriptorBuilder* call_descriptor_builder, + RawMachineAssembler(Graph* graph, MachineSignature* machine_sig, MachineType word = kMachPtr); virtual ~RawMachineAssembler() {} @@ -54,18 +53,12 @@ class RawMachineAssembler : public GraphBuilder, Zone* zone() const { return graph()->zone(); } MachineOperatorBuilder* machine() { return &machine_; } CommonOperatorBuilder* common() { return &common_; } - CallDescriptor* call_descriptor() const { - return call_descriptor_builder_->BuildCallDescriptor(zone()); - } - int parameter_count() const { - return call_descriptor_builder_->parameter_count(); - } - const MachineType* parameter_types() const { - return call_descriptor_builder_->parameter_types(); - } + CallDescriptor* call_descriptor() const { return call_descriptor_; } + size_t parameter_count() const { return machine_sig_->parameter_count(); } + MachineSignature* machine_sig() const { return machine_sig_; } // Parameters. - Node* Parameter(int index); + Node* Parameter(size_t index); // Control flow. Label* Exit(); @@ -75,9 +68,10 @@ class RawMachineAssembler : public GraphBuilder, Node* CallFunctionStub0(Node* function, Node* receiver, Node* context, Node* frame_state, CallFunctionFlags flags); // Call to a JS function with zero parameters. - Node* CallJS0(Node* function, Node* receiver, Node* frame_state); + Node* CallJS0(Node* function, Node* receiver, Node* context, + Node* frame_state); // Call to a runtime function with zero parameters. - Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, + Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context, Node* frame_state); void Return(Node* value); void Bind(Label* label); @@ -113,7 +107,8 @@ class RawMachineAssembler : public GraphBuilder, Schedule* schedule_; MachineOperatorBuilder machine_; CommonOperatorBuilder common_; - MachineCallDescriptorBuilder* call_descriptor_builder_; + MachineSignature* machine_sig_; + CallDescriptor* call_descriptor_; Node** parameters_; Label exit_label_; BasicBlock* current_block_; diff --git a/src/compiler/structured-machine-assembler.cc b/src/compiler/structured-machine-assembler.cc index 56da5fb..6475809 100644 --- a/src/compiler/structured-machine-assembler.cc +++ b/src/compiler/structured-machine-assembler.cc @@ -17,23 +17,26 @@ void Variable::Set(Node* value) const { smasm_->SetVariable(offset_, value); } StructuredMachineAssembler::StructuredMachineAssembler( - Graph* graph, MachineCallDescriptorBuilder* call_descriptor_builder, - MachineType word) + Graph* graph, MachineSignature* machine_sig, MachineType word) : GraphBuilder(graph), schedule_(new (zone()) Schedule(zone())), machine_(zone(), word), common_(zone()), - call_descriptor_builder_(call_descriptor_builder), + machine_sig_(machine_sig), + call_descriptor_( + Linkage::GetSimplifiedCDescriptor(graph->zone(), machine_sig)), parameters_(NULL), current_environment_(new (zone()) Environment(zone(), schedule()->start(), false)), number_of_variables_(0) { - Node* s = graph->NewNode(common_.Start(parameter_count())); + int param_count = static_cast(parameter_count()); + Node* s = graph->NewNode(common_.Start(param_count)); graph->SetStart(s); if (parameter_count() == 0) return; - parameters_ = zone()->NewArray(parameter_count()); - for (int i = 0; i < parameter_count(); ++i) { - parameters_[i] = NewNode(common()->Parameter(i), graph->start()); + parameters_ = zone()->NewArray(param_count); + for (size_t i = 0; i < parameter_count(); ++i) { + parameters_[i] = + NewNode(common()->Parameter(static_cast(i)), graph->start()); } } @@ -49,8 +52,8 @@ Schedule* StructuredMachineAssembler::Export() { } -Node* StructuredMachineAssembler::Parameter(int index) { - DCHECK(0 <= index && index < parameter_count()); +Node* StructuredMachineAssembler::Parameter(size_t index) { + DCHECK(index < parameter_count()); return parameters_[index]; } diff --git a/src/compiler/structured-machine-assembler.h b/src/compiler/structured-machine-assembler.h index 7fe34a1..5f683a3 100644 --- a/src/compiler/structured-machine-assembler.h +++ b/src/compiler/structured-machine-assembler.h @@ -61,27 +61,20 @@ class StructuredMachineAssembler class LoopBuilder; friend class LoopBuilder; - StructuredMachineAssembler( - Graph* graph, MachineCallDescriptorBuilder* call_descriptor_builder, - MachineType word = kMachPtr); + StructuredMachineAssembler(Graph* graph, MachineSignature* machine_sig, + MachineType word = kMachPtr); virtual ~StructuredMachineAssembler() {} Isolate* isolate() const { return zone()->isolate(); } Zone* zone() const { return graph()->zone(); } MachineOperatorBuilder* machine() { return &machine_; } CommonOperatorBuilder* common() { return &common_; } - CallDescriptor* call_descriptor() const { - return call_descriptor_builder_->BuildCallDescriptor(zone()); - } - int parameter_count() const { - return call_descriptor_builder_->parameter_count(); - } - const MachineType* parameter_types() const { - return call_descriptor_builder_->parameter_types(); - } + CallDescriptor* call_descriptor() const { return call_descriptor_; } + size_t parameter_count() const { return machine_sig_->parameter_count(); } + MachineSignature* machine_sig() const { return machine_sig_; } // Parameters. - Node* Parameter(int index); + Node* Parameter(size_t index); // Variables. Variable NewVariable(Node* initial_value); // Control flow. @@ -126,7 +119,8 @@ class StructuredMachineAssembler Schedule* schedule_; MachineOperatorBuilder machine_; CommonOperatorBuilder common_; - MachineCallDescriptorBuilder* call_descriptor_builder_; + MachineSignature* machine_sig_; + CallDescriptor* call_descriptor_; Node** parameters_; Environment* current_environment_; int number_of_variables_; diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc index 30c43d6..a489615 100644 --- a/src/compiler/x64/code-generator-x64.cc +++ b/src/compiler/x64/code-generator-x64.cc @@ -226,9 +226,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { } break; case kArchCallJSFunction: { - // TODO(jarin) The load of the context should be separated from the call. Register func = i.InputRegister(0); - __ movp(rsi, FieldOperand(func, JSFunction::kContextOffset)); + if (FLAG_debug_code) { + // Check the function's context matches the context argument. + __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); + __ Assert(equal, kWrongFunctionContext); + } __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); AddSafepointAndDeopt(instr); break; @@ -858,8 +861,9 @@ void CodeGenerator::AssembleReturn() { } else { __ movq(rsp, rbp); // Move stack pointer back to frame pointer. __ popq(rbp); // Pop caller's frame pointer. - int pop_count = - descriptor->IsJSFunctionCall() ? descriptor->ParameterCount() : 0; + int pop_count = descriptor->IsJSFunctionCall() + ? static_cast(descriptor->JSParameterCount()) + : 0; __ ret(pop_count * kPointerSize); } } diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc index b370e96..25b8d85 100644 --- a/src/compiler/x64/instruction-selector-x64.cc +++ b/src/compiler/x64/instruction-selector-x64.cc @@ -671,8 +671,8 @@ void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, FrameStateDescriptor* frame_state_descriptor = NULL; if (descriptor->NeedsFrameState()) { - frame_state_descriptor = - GetFrameStateDescriptor(call->InputAt(descriptor->InputCount())); + frame_state_descriptor = GetFrameStateDescriptor( + call->InputAt(static_cast(descriptor->InputCount()))); } CallBuffer buffer(zone(), descriptor, frame_state_descriptor); diff --git a/src/compiler/x64/linkage-x64.cc b/src/compiler/x64/linkage-x64.cc index c106b7b..4ea9cc8 100644 --- a/src/compiler/x64/linkage-x64.cc +++ b/src/compiler/x64/linkage-x64.cc @@ -20,7 +20,7 @@ const bool kWin64 = true; const bool kWin64 = false; #endif -struct LinkageHelperTraits { +struct X64LinkageHelperTraits { static Register ReturnValueReg() { return rax; } static Register ReturnValue2Reg() { return rdx; } static Register JSCallFunctionReg() { return rdi; } @@ -47,34 +47,32 @@ struct LinkageHelperTraits { static int CRegisterParametersLength() { return kWin64 ? 4 : 6; } }; +typedef LinkageHelper LH; CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) { - return LinkageHelper::GetJSCallDescriptor( - zone, parameter_count); + return LH::GetJSCallDescriptor(zone, parameter_count); } CallDescriptor* Linkage::GetRuntimeCallDescriptor( Runtime::FunctionId function, int parameter_count, Operator::Properties properties, Zone* zone) { - return LinkageHelper::GetRuntimeCallDescriptor( - zone, function, parameter_count, properties); + return LH::GetRuntimeCallDescriptor(zone, function, parameter_count, + properties); } CallDescriptor* Linkage::GetStubCallDescriptor( CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count, CallDescriptor::Flags flags, Zone* zone) { - return LinkageHelper::GetStubCallDescriptor( - zone, descriptor, stack_parameter_count, flags); + return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count, + flags); } -CallDescriptor* Linkage::GetSimplifiedCDescriptor( - Zone* zone, int num_params, MachineType return_type, - const MachineType* param_types) { - return LinkageHelper::GetSimplifiedCDescriptor( - zone, num_params, return_type, param_types); +CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone, + MachineSignature* sig) { + return LH::GetSimplifiedCDescriptor(zone, sig); } } // namespace compiler diff --git a/src/objects.h b/src/objects.h index 7a4ff33..e2fac8e 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1023,321 +1023,322 @@ template inline bool Is(Object* obj); V(OrderedHashTable) -#define ERROR_MESSAGES_LIST(V) \ - V(kNoReason, "no reason") \ - \ - V(k32BitValueInRegisterIsNotZeroExtended, \ - "32 bit value in register is not zero-extended") \ - V(kAlignmentMarkerExpected, "Alignment marker expected") \ - V(kAllocationIsNotDoubleAligned, "Allocation is not double aligned") \ - V(kAPICallReturnedInvalidObject, "API call returned invalid object") \ - V(kArgumentsObjectValueInATestContext, \ - "Arguments object value in a test context") \ - V(kArrayBoilerplateCreationFailed, "Array boilerplate creation failed") \ - V(kArrayIndexConstantValueTooBig, "Array index constant value too big") \ - V(kAssignmentToArguments, "Assignment to arguments") \ - V(kAssignmentToLetVariableBeforeInitialization, \ - "Assignment to let variable before initialization") \ - V(kAssignmentToLOOKUPVariable, "Assignment to LOOKUP variable") \ - V(kAssignmentToParameterFunctionUsesArgumentsObject, \ - "Assignment to parameter, function uses arguments object") \ - V(kAssignmentToParameterInArgumentsObject, \ - "Assignment to parameter in arguments object") \ - V(kAttemptToUseUndefinedCache, "Attempt to use undefined cache") \ - V(kBadValueContextForArgumentsObjectValue, \ - "Bad value context for arguments object value") \ - V(kBadValueContextForArgumentsValue, \ - "Bad value context for arguments value") \ - V(kBailedOutDueToDependencyChange, "Bailed out due to dependency change") \ - V(kBailoutWasNotPrepared, "Bailout was not prepared") \ - V(kBinaryStubGenerateFloatingPointCode, \ - "BinaryStub_GenerateFloatingPointCode") \ - V(kBothRegistersWereSmisInSelectNonSmi, \ - "Both registers were smis in SelectNonSmi") \ - V(kCallToAJavaScriptRuntimeFunction, \ - "Call to a JavaScript runtime function") \ - V(kCannotTranslatePositionInChangedArea, \ - "Cannot translate position in changed area") \ - V(kCodeGenerationFailed, "Code generation failed") \ - V(kCodeObjectNotProperlyPatched, "Code object not properly patched") \ - V(kCompoundAssignmentToLookupSlot, "Compound assignment to lookup slot") \ - V(kContextAllocatedArguments, "Context-allocated arguments") \ - V(kCopyBuffersOverlap, "Copy buffers overlap") \ - V(kCouldNotGenerateZero, "Could not generate +0.0") \ - V(kCouldNotGenerateNegativeZero, "Could not generate -0.0") \ - V(kDebuggerHasBreakPoints, "Debugger has break points") \ - V(kDebuggerStatement, "DebuggerStatement") \ - V(kDeclarationInCatchContext, "Declaration in catch context") \ - V(kDeclarationInWithContext, "Declaration in with context") \ - V(kDefaultNaNModeNotSet, "Default NaN mode not set") \ - V(kDeleteWithGlobalVariable, "Delete with global variable") \ - V(kDeleteWithNonGlobalVariable, "Delete with non-global variable") \ - V(kDestinationOfCopyNotAligned, "Destination of copy not aligned") \ - V(kDontDeleteCellsCannotContainTheHole, \ - "DontDelete cells can't contain the hole") \ - V(kDoPushArgumentNotImplementedForDoubleType, \ - "DoPushArgument not implemented for double type") \ - V(kEliminatedBoundsCheckFailed, "Eliminated bounds check failed") \ - V(kEmitLoadRegisterUnsupportedDoubleImmediate, \ - "EmitLoadRegister: Unsupported double immediate") \ - V(kEval, "eval") \ - V(kExpected0AsASmiSentinel, "Expected 0 as a Smi sentinel") \ - V(kExpectedAlignmentMarker, "Expected alignment marker") \ - V(kExpectedAllocationSite, "Expected allocation site") \ - V(kExpectedFunctionObject, "Expected function object in register") \ - V(kExpectedHeapNumber, "Expected HeapNumber") \ - V(kExpectedNativeContext, "Expected native context") \ - V(kExpectedNonIdenticalObjects, "Expected non-identical objects") \ - V(kExpectedNonNullContext, "Expected non-null context") \ - V(kExpectedPositiveZero, "Expected +0.0") \ - V(kExpectedAllocationSiteInCell, "Expected AllocationSite in property cell")\ - V(kExpectedFixedArrayInFeedbackVector, \ - "Expected fixed array in feedback vector") \ - V(kExpectedFixedArrayInRegisterA2, "Expected fixed array in register a2") \ - V(kExpectedFixedArrayInRegisterEbx, "Expected fixed array in register ebx") \ - V(kExpectedFixedArrayInRegisterR2, "Expected fixed array in register r2") \ - V(kExpectedFixedArrayInRegisterRbx, "Expected fixed array in register rbx") \ - V(kExpectedNewSpaceObject, "Expected new space object") \ - V(kExpectedSmiOrHeapNumber, "Expected smi or HeapNumber") \ - V(kExpectedUndefinedOrCell, "Expected undefined or cell in register") \ - V(kExpectingAlignmentForCopyBytes, "Expecting alignment for CopyBytes") \ - V(kExportDeclaration, "Export declaration") \ - V(kExternalStringExpectedButNotFound, \ - "External string expected, but not found") \ - V(kFailedBailedOutLastTime, "Failed/bailed out last time") \ - V(kForInStatementIsNotFastCase, "ForInStatement is not fast case") \ - V(kForInStatementOptimizationIsDisabled, \ - "ForInStatement optimization is disabled") \ - V(kForInStatementWithNonLocalEachVariable, \ - "ForInStatement with non-local each variable") \ - V(kForOfStatement, "ForOfStatement") \ - V(kFrameIsExpectedToBeAligned, "Frame is expected to be aligned") \ - V(kFunctionCallsEval, "Function calls eval") \ - V(kFunctionIsAGenerator, "Function is a generator") \ - V(kFunctionWithIllegalRedeclaration, "Function with illegal redeclaration") \ - V(kGeneratedCodeIsTooLarge, "Generated code is too large") \ - V(kGeneratorFailedToResume, "Generator failed to resume") \ - V(kGenerator, "Generator") \ - V(kGlobalFunctionsMustHaveInitialMap, \ - "Global functions must have initial map") \ - V(kHeapNumberMapRegisterClobbered, "HeapNumberMap register clobbered") \ - V(kHydrogenFilter, "Optimization disabled by filter") \ - V(kImportDeclaration, "Import declaration") \ - V(kImproperObjectOnPrototypeChainForStore, \ - "Improper object on prototype chain for store") \ - V(kIndexIsNegative, "Index is negative") \ - V(kIndexIsTooLarge, "Index is too large") \ - V(kInlinedRuntimeFunctionClassOf, "Inlined runtime function: ClassOf") \ - V(kInlinedRuntimeFunctionFastAsciiArrayJoin, \ - "Inlined runtime function: FastAsciiArrayJoin") \ - V(kInlinedRuntimeFunctionGeneratorNext, \ - "Inlined runtime function: GeneratorNext") \ - V(kInlinedRuntimeFunctionGeneratorThrow, \ - "Inlined runtime function: GeneratorThrow") \ - V(kInlinedRuntimeFunctionGetFromCache, \ - "Inlined runtime function: GetFromCache") \ - V(kInlinedRuntimeFunctionIsNonNegativeSmi, \ - "Inlined runtime function: IsNonNegativeSmi") \ - V(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf, \ - "Inlined runtime function: IsStringWrapperSafeForDefaultValueOf") \ - V(kInliningBailedOut, "Inlining bailed out") \ - V(kInputGPRIsExpectedToHaveUpper32Cleared, \ - "Input GPR is expected to have upper32 cleared") \ - V(kInputStringTooLong, "Input string too long") \ - V(kInstanceofStubUnexpectedCallSiteCacheCheck, \ - "InstanceofStub unexpected call site cache (check)") \ - V(kInstanceofStubUnexpectedCallSiteCacheCmp1, \ - "InstanceofStub unexpected call site cache (cmp 1)") \ - V(kInstanceofStubUnexpectedCallSiteCacheCmp2, \ - "InstanceofStub unexpected call site cache (cmp 2)") \ - V(kInstanceofStubUnexpectedCallSiteCacheMov, \ - "InstanceofStub unexpected call site cache (mov)") \ - V(kInteger32ToSmiFieldWritingToNonSmiLocation, \ - "Integer32ToSmiField writing to non-smi location") \ - V(kInvalidCaptureReferenced, "Invalid capture referenced") \ - V(kInvalidElementsKindForInternalArrayOrInternalPackedArray, \ - "Invalid ElementsKind for InternalArray or InternalPackedArray") \ - V(kInvalidFullCodegenState, "invalid full-codegen state") \ - V(kInvalidHandleScopeLevel, "Invalid HandleScope level") \ - V(kInvalidLeftHandSideInAssignment, "Invalid left-hand side in assignment") \ - V(kInvalidLhsInCompoundAssignment, "Invalid lhs in compound assignment") \ - V(kInvalidLhsInCountOperation, "Invalid lhs in count operation") \ - V(kInvalidMinLength, "Invalid min_length") \ - V(kJSGlobalObjectNativeContextShouldBeANativeContext, \ - "JSGlobalObject::native_context should be a native context") \ - V(kJSGlobalProxyContextShouldNotBeNull, \ - "JSGlobalProxy::context() should not be null") \ - V(kJSObjectWithFastElementsMapHasSlowElements, \ - "JSObject with fast elements map has slow elements") \ - V(kLetBindingReInitialization, "Let binding re-initialization") \ - V(kLhsHasBeenClobbered, "lhs has been clobbered") \ - V(kLiveBytesCountOverflowChunkSize, "Live Bytes Count overflow chunk size") \ - V(kLiveEdit, "LiveEdit") \ - V(kLookupVariableInCountOperation, "Lookup variable in count operation") \ - V(kMapBecameDeprecated, "Map became deprecated") \ - V(kMapBecameUnstable, "Map became unstable") \ - V(kMapIsNoLongerInEax, "Map is no longer in eax") \ - V(kModuleDeclaration, "Module declaration") \ - V(kModuleLiteral, "Module literal") \ - V(kModulePath, "Module path") \ - V(kModuleStatement, "Module statement") \ - V(kModuleVariable, "Module variable") \ - V(kModuleUrl, "Module url") \ - V(kNativeFunctionLiteral, "Native function literal") \ - V(kSuperReference, "Super reference") \ - V(kNeedSmiLiteral, "Need a Smi literal here") \ - V(kNoCasesLeft, "No cases left") \ - V(kNoEmptyArraysHereInEmitFastAsciiArrayJoin, \ - "No empty arrays here in EmitFastAsciiArrayJoin") \ - V(kNonInitializerAssignmentToConst, "Non-initializer assignment to const") \ - V(kNonSmiIndex, "Non-smi index") \ - V(kNonSmiKeyInArrayLiteral, "Non-smi key in array literal") \ - V(kNonSmiValue, "Non-smi value") \ - V(kNonObject, "Non-object value") \ - V(kNotEnoughVirtualRegistersForValues, \ - "Not enough virtual registers for values") \ - V(kNotEnoughSpillSlotsForOsr, "Not enough spill slots for OSR") \ - V(kNotEnoughVirtualRegistersRegalloc, \ - "Not enough virtual registers (regalloc)") \ - V(kObjectFoundInSmiOnlyArray, "Object found in smi-only array") \ - V(kObjectLiteralWithComplexProperty, "Object literal with complex property")\ - V(kOddballInStringTableIsNotUndefinedOrTheHole, \ - "Oddball in string table is not undefined or the hole") \ - V(kOffsetOutOfRange, "Offset out of range") \ - V(kOperandIsASmiAndNotAName, "Operand is a smi and not a name") \ - V(kOperandIsASmiAndNotAString, "Operand is a smi and not a string") \ - V(kOperandIsASmi, "Operand is a smi") \ - V(kOperandIsNotAName, "Operand is not a name") \ - V(kOperandIsNotANumber, "Operand is not a number") \ - V(kOperandIsNotASmi, "Operand is not a smi") \ - V(kOperandIsNotAString, "Operand is not a string") \ - V(kOperandIsNotSmi, "Operand is not smi") \ - V(kOperandNotANumber, "Operand not a number") \ - V(kObjectTagged, "The object is tagged") \ - V(kObjectNotTagged, "The object is not tagged") \ - V(kOptimizationDisabled, "Optimization is disabled") \ - V(kOptimizedTooManyTimes, "Optimized too many times") \ - V(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister, \ - "Out of virtual registers while trying to allocate temp register") \ - V(kParseScopeError, "Parse/scope error") \ - V(kPossibleDirectCallToEval, "Possible direct call to eval") \ - V(kPreconditionsWereNotMet, "Preconditions were not met") \ - V(kPropertyAllocationCountFailed, "Property allocation count failed") \ - V(kReceivedInvalidReturnAddress, "Received invalid return address") \ - V(kReferenceToAVariableWhichRequiresDynamicLookup, \ - "Reference to a variable which requires dynamic lookup") \ - V(kReferenceToGlobalLexicalVariable, "Reference to global lexical variable")\ - V(kReferenceToUninitializedVariable, "Reference to uninitialized variable") \ - V(kRegisterDidNotMatchExpectedRoot, "Register did not match expected root") \ - V(kRegisterWasClobbered, "Register was clobbered") \ - V(kRememberedSetPointerInNewSpace, "Remembered set pointer is in new space")\ - V(kReturnAddressNotFoundInFrame, "Return address not found in frame") \ - V(kRhsHasBeenClobbered, "Rhs has been clobbered") \ - V(kScopedBlock, "ScopedBlock") \ - V(kSmiAdditionOverflow, "Smi addition overflow") \ - V(kSmiSubtractionOverflow, "Smi subtraction overflow") \ - V(kStackAccessBelowStackPointer, "Stack access below stack pointer") \ - V(kStackFrameTypesMustMatch, "Stack frame types must match") \ - V(kSwitchStatementMixedOrNonLiteralSwitchLabels, \ - "SwitchStatement: mixed or non-literal switch labels") \ - V(kSwitchStatementTooManyClauses, "SwitchStatement: too many clauses") \ - V(kTheCurrentStackPointerIsBelowCsp, \ - "The current stack pointer is below csp") \ - V(kTheInstructionShouldBeALui, "The instruction should be a lui") \ - V(kTheInstructionShouldBeAnOri, "The instruction should be an ori") \ - V(kTheInstructionToPatchShouldBeALoadFromConstantPool, \ - "The instruction to patch should be a load from the constant pool") \ - V(kTheInstructionToPatchShouldBeAnLdrLiteral, \ - "The instruction to patch should be a ldr literal") \ - V(kTheInstructionToPatchShouldBeALui, \ - "The instruction to patch should be a lui") \ - V(kTheInstructionToPatchShouldBeAnOri, \ - "The instruction to patch should be an ori") \ - V(kTheSourceAndDestinationAreTheSame, \ - "The source and destination are the same") \ - V(kTheStackPointerIsNotAligned, "The stack pointer is not aligned.") \ - V(kTheStackWasCorruptedByMacroAssemblerCall, \ - "The stack was corrupted by MacroAssembler::Call()") \ - V(kTooManyParametersLocals, "Too many parameters/locals") \ - V(kTooManyParameters, "Too many parameters") \ - V(kTooManySpillSlotsNeededForOSR, "Too many spill slots needed for OSR") \ - V(kToOperand32UnsupportedImmediate, "ToOperand32 unsupported immediate.") \ - V(kToOperandIsDoubleRegisterUnimplemented, \ - "ToOperand IsDoubleRegister unimplemented") \ - V(kToOperandUnsupportedDoubleImmediate, \ - "ToOperand Unsupported double immediate") \ - V(kTryCatchStatement, "TryCatchStatement") \ - V(kTryFinallyStatement, "TryFinallyStatement") \ - V(kUnableToEncodeValueAsSmi, "Unable to encode value as smi") \ - V(kUnalignedAllocationInNewSpace, "Unaligned allocation in new space") \ - V(kUnalignedCellInWriteBarrier, "Unaligned cell in write barrier") \ - V(kUndefinedValueNotLoaded, "Undefined value not loaded") \ - V(kUndoAllocationOfNonAllocatedMemory, \ - "Undo allocation of non allocated memory") \ - V(kUnexpectedAllocationTop, "Unexpected allocation top") \ - V(kUnexpectedColorFound, "Unexpected color bit pattern found") \ - V(kUnexpectedElementsKindInArrayConstructor, \ - "Unexpected ElementsKind in array constructor") \ - V(kUnexpectedFallthroughFromCharCodeAtSlowCase, \ - "Unexpected fallthrough from CharCodeAt slow case") \ - V(kUnexpectedFallthroughFromCharFromCodeSlowCase, \ - "Unexpected fallthrough from CharFromCode slow case") \ - V(kUnexpectedFallThroughFromStringComparison, \ - "Unexpected fall-through from string comparison") \ - V(kUnexpectedFallThroughInBinaryStubGenerateFloatingPointCode, \ - "Unexpected fall-through in BinaryStub_GenerateFloatingPointCode") \ - V(kUnexpectedFallthroughToCharCodeAtSlowCase, \ - "Unexpected fallthrough to CharCodeAt slow case") \ - V(kUnexpectedFallthroughToCharFromCodeSlowCase, \ - "Unexpected fallthrough to CharFromCode slow case") \ - V(kUnexpectedFPUStackDepthAfterInstruction, \ - "Unexpected FPU stack depth after instruction") \ - V(kUnexpectedInitialMapForArrayFunction1, \ - "Unexpected initial map for Array function (1)") \ - V(kUnexpectedInitialMapForArrayFunction2, \ - "Unexpected initial map for Array function (2)") \ - V(kUnexpectedInitialMapForArrayFunction, \ - "Unexpected initial map for Array function") \ - V(kUnexpectedInitialMapForInternalArrayFunction, \ - "Unexpected initial map for InternalArray function") \ - V(kUnexpectedLevelAfterReturnFromApiCall, \ - "Unexpected level after return from api call") \ - V(kUnexpectedNegativeValue, "Unexpected negative value") \ - V(kUnexpectedNumberOfPreAllocatedPropertyFields, \ - "Unexpected number of pre-allocated property fields") \ - V(kUnexpectedFPCRMode, "Unexpected FPCR mode.") \ - V(kUnexpectedSmi, "Unexpected smi value") \ - V(kUnexpectedStringFunction, "Unexpected String function") \ - V(kUnexpectedStringType, "Unexpected string type") \ - V(kUnexpectedStringWrapperInstanceSize, \ - "Unexpected string wrapper instance size") \ - V(kUnexpectedTypeForRegExpDataFixedArrayExpected, \ - "Unexpected type for RegExp data, FixedArray expected") \ - V(kUnexpectedValue, "Unexpected value") \ - V(kUnexpectedUnusedPropertiesOfStringWrapper, \ - "Unexpected unused properties of string wrapper") \ - V(kUnimplemented, "unimplemented") \ - V(kUninitializedKSmiConstantRegister, "Uninitialized kSmiConstantRegister") \ - V(kUnknown, "Unknown") \ - V(kUnsupportedConstCompoundAssignment, \ - "Unsupported const compound assignment") \ - V(kUnsupportedCountOperationWithConst, \ - "Unsupported count operation with const") \ - V(kUnsupportedDoubleImmediate, "Unsupported double immediate") \ - V(kUnsupportedLetCompoundAssignment, "Unsupported let compound assignment") \ - V(kUnsupportedLookupSlotInDeclaration, \ - "Unsupported lookup slot in declaration") \ - V(kUnsupportedNonPrimitiveCompare, "Unsupported non-primitive compare") \ - V(kUnsupportedPhiUseOfArguments, "Unsupported phi use of arguments") \ - V(kUnsupportedPhiUseOfConstVariable, \ - "Unsupported phi use of const variable") \ - V(kUnsupportedTaggedImmediate, "Unsupported tagged immediate") \ - V(kVariableResolvedToWithContext, "Variable resolved to with context") \ - V(kWeShouldNotHaveAnEmptyLexicalContext, \ - "We should not have an empty lexical context") \ - V(kWithStatement, "WithStatement") \ - V(kWrongAddressOrValuePassedToRecordWrite, \ - "Wrong address or value passed to RecordWrite") \ +#define ERROR_MESSAGES_LIST(V) \ + V(kNoReason, "no reason") \ + \ + V(k32BitValueInRegisterIsNotZeroExtended, \ + "32 bit value in register is not zero-extended") \ + V(kAlignmentMarkerExpected, "Alignment marker expected") \ + V(kAllocationIsNotDoubleAligned, "Allocation is not double aligned") \ + V(kAPICallReturnedInvalidObject, "API call returned invalid object") \ + V(kArgumentsObjectValueInATestContext, \ + "Arguments object value in a test context") \ + V(kArrayBoilerplateCreationFailed, "Array boilerplate creation failed") \ + V(kArrayIndexConstantValueTooBig, "Array index constant value too big") \ + V(kAssignmentToArguments, "Assignment to arguments") \ + V(kAssignmentToLetVariableBeforeInitialization, \ + "Assignment to let variable before initialization") \ + V(kAssignmentToLOOKUPVariable, "Assignment to LOOKUP variable") \ + V(kAssignmentToParameterFunctionUsesArgumentsObject, \ + "Assignment to parameter, function uses arguments object") \ + V(kAssignmentToParameterInArgumentsObject, \ + "Assignment to parameter in arguments object") \ + V(kAttemptToUseUndefinedCache, "Attempt to use undefined cache") \ + V(kBadValueContextForArgumentsObjectValue, \ + "Bad value context for arguments object value") \ + V(kBadValueContextForArgumentsValue, \ + "Bad value context for arguments value") \ + V(kBailedOutDueToDependencyChange, "Bailed out due to dependency change") \ + V(kBailoutWasNotPrepared, "Bailout was not prepared") \ + V(kBinaryStubGenerateFloatingPointCode, \ + "BinaryStub_GenerateFloatingPointCode") \ + V(kBothRegistersWereSmisInSelectNonSmi, \ + "Both registers were smis in SelectNonSmi") \ + V(kCallToAJavaScriptRuntimeFunction, \ + "Call to a JavaScript runtime function") \ + V(kCannotTranslatePositionInChangedArea, \ + "Cannot translate position in changed area") \ + V(kCodeGenerationFailed, "Code generation failed") \ + V(kCodeObjectNotProperlyPatched, "Code object not properly patched") \ + V(kCompoundAssignmentToLookupSlot, "Compound assignment to lookup slot") \ + V(kContextAllocatedArguments, "Context-allocated arguments") \ + V(kCopyBuffersOverlap, "Copy buffers overlap") \ + V(kCouldNotGenerateZero, "Could not generate +0.0") \ + V(kCouldNotGenerateNegativeZero, "Could not generate -0.0") \ + V(kDebuggerHasBreakPoints, "Debugger has break points") \ + V(kDebuggerStatement, "DebuggerStatement") \ + V(kDeclarationInCatchContext, "Declaration in catch context") \ + V(kDeclarationInWithContext, "Declaration in with context") \ + V(kDefaultNaNModeNotSet, "Default NaN mode not set") \ + V(kDeleteWithGlobalVariable, "Delete with global variable") \ + V(kDeleteWithNonGlobalVariable, "Delete with non-global variable") \ + V(kDestinationOfCopyNotAligned, "Destination of copy not aligned") \ + V(kDontDeleteCellsCannotContainTheHole, \ + "DontDelete cells can't contain the hole") \ + V(kDoPushArgumentNotImplementedForDoubleType, \ + "DoPushArgument not implemented for double type") \ + V(kEliminatedBoundsCheckFailed, "Eliminated bounds check failed") \ + V(kEmitLoadRegisterUnsupportedDoubleImmediate, \ + "EmitLoadRegister: Unsupported double immediate") \ + V(kEval, "eval") \ + V(kExpected0AsASmiSentinel, "Expected 0 as a Smi sentinel") \ + V(kExpectedAlignmentMarker, "Expected alignment marker") \ + V(kExpectedAllocationSite, "Expected allocation site") \ + V(kExpectedFunctionObject, "Expected function object in register") \ + V(kExpectedHeapNumber, "Expected HeapNumber") \ + V(kExpectedNativeContext, "Expected native context") \ + V(kExpectedNonIdenticalObjects, "Expected non-identical objects") \ + V(kExpectedNonNullContext, "Expected non-null context") \ + V(kExpectedPositiveZero, "Expected +0.0") \ + V(kExpectedAllocationSiteInCell, "Expected AllocationSite in property cell") \ + V(kExpectedFixedArrayInFeedbackVector, \ + "Expected fixed array in feedback vector") \ + V(kExpectedFixedArrayInRegisterA2, "Expected fixed array in register a2") \ + V(kExpectedFixedArrayInRegisterEbx, "Expected fixed array in register ebx") \ + V(kExpectedFixedArrayInRegisterR2, "Expected fixed array in register r2") \ + V(kExpectedFixedArrayInRegisterRbx, "Expected fixed array in register rbx") \ + V(kExpectedNewSpaceObject, "Expected new space object") \ + V(kExpectedSmiOrHeapNumber, "Expected smi or HeapNumber") \ + V(kExpectedUndefinedOrCell, "Expected undefined or cell in register") \ + V(kExpectingAlignmentForCopyBytes, "Expecting alignment for CopyBytes") \ + V(kExportDeclaration, "Export declaration") \ + V(kExternalStringExpectedButNotFound, \ + "External string expected, but not found") \ + V(kFailedBailedOutLastTime, "Failed/bailed out last time") \ + V(kForInStatementIsNotFastCase, "ForInStatement is not fast case") \ + V(kForInStatementOptimizationIsDisabled, \ + "ForInStatement optimization is disabled") \ + V(kForInStatementWithNonLocalEachVariable, \ + "ForInStatement with non-local each variable") \ + V(kForOfStatement, "ForOfStatement") \ + V(kFrameIsExpectedToBeAligned, "Frame is expected to be aligned") \ + V(kFunctionCallsEval, "Function calls eval") \ + V(kFunctionIsAGenerator, "Function is a generator") \ + V(kFunctionWithIllegalRedeclaration, "Function with illegal redeclaration") \ + V(kGeneratedCodeIsTooLarge, "Generated code is too large") \ + V(kGeneratorFailedToResume, "Generator failed to resume") \ + V(kGenerator, "Generator") \ + V(kGlobalFunctionsMustHaveInitialMap, \ + "Global functions must have initial map") \ + V(kHeapNumberMapRegisterClobbered, "HeapNumberMap register clobbered") \ + V(kHydrogenFilter, "Optimization disabled by filter") \ + V(kImportDeclaration, "Import declaration") \ + V(kImproperObjectOnPrototypeChainForStore, \ + "Improper object on prototype chain for store") \ + V(kIndexIsNegative, "Index is negative") \ + V(kIndexIsTooLarge, "Index is too large") \ + V(kInlinedRuntimeFunctionClassOf, "Inlined runtime function: ClassOf") \ + V(kInlinedRuntimeFunctionFastAsciiArrayJoin, \ + "Inlined runtime function: FastAsciiArrayJoin") \ + V(kInlinedRuntimeFunctionGeneratorNext, \ + "Inlined runtime function: GeneratorNext") \ + V(kInlinedRuntimeFunctionGeneratorThrow, \ + "Inlined runtime function: GeneratorThrow") \ + V(kInlinedRuntimeFunctionGetFromCache, \ + "Inlined runtime function: GetFromCache") \ + V(kInlinedRuntimeFunctionIsNonNegativeSmi, \ + "Inlined runtime function: IsNonNegativeSmi") \ + V(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf, \ + "Inlined runtime function: IsStringWrapperSafeForDefaultValueOf") \ + V(kInliningBailedOut, "Inlining bailed out") \ + V(kInputGPRIsExpectedToHaveUpper32Cleared, \ + "Input GPR is expected to have upper32 cleared") \ + V(kInputStringTooLong, "Input string too long") \ + V(kInstanceofStubUnexpectedCallSiteCacheCheck, \ + "InstanceofStub unexpected call site cache (check)") \ + V(kInstanceofStubUnexpectedCallSiteCacheCmp1, \ + "InstanceofStub unexpected call site cache (cmp 1)") \ + V(kInstanceofStubUnexpectedCallSiteCacheCmp2, \ + "InstanceofStub unexpected call site cache (cmp 2)") \ + V(kInstanceofStubUnexpectedCallSiteCacheMov, \ + "InstanceofStub unexpected call site cache (mov)") \ + V(kInteger32ToSmiFieldWritingToNonSmiLocation, \ + "Integer32ToSmiField writing to non-smi location") \ + V(kInvalidCaptureReferenced, "Invalid capture referenced") \ + V(kInvalidElementsKindForInternalArrayOrInternalPackedArray, \ + "Invalid ElementsKind for InternalArray or InternalPackedArray") \ + V(kInvalidFullCodegenState, "invalid full-codegen state") \ + V(kInvalidHandleScopeLevel, "Invalid HandleScope level") \ + V(kInvalidLeftHandSideInAssignment, "Invalid left-hand side in assignment") \ + V(kInvalidLhsInCompoundAssignment, "Invalid lhs in compound assignment") \ + V(kInvalidLhsInCountOperation, "Invalid lhs in count operation") \ + V(kInvalidMinLength, "Invalid min_length") \ + V(kJSGlobalObjectNativeContextShouldBeANativeContext, \ + "JSGlobalObject::native_context should be a native context") \ + V(kJSGlobalProxyContextShouldNotBeNull, \ + "JSGlobalProxy::context() should not be null") \ + V(kJSObjectWithFastElementsMapHasSlowElements, \ + "JSObject with fast elements map has slow elements") \ + V(kLetBindingReInitialization, "Let binding re-initialization") \ + V(kLhsHasBeenClobbered, "lhs has been clobbered") \ + V(kLiveBytesCountOverflowChunkSize, "Live Bytes Count overflow chunk size") \ + V(kLiveEdit, "LiveEdit") \ + V(kLookupVariableInCountOperation, "Lookup variable in count operation") \ + V(kMapBecameDeprecated, "Map became deprecated") \ + V(kMapBecameUnstable, "Map became unstable") \ + V(kMapIsNoLongerInEax, "Map is no longer in eax") \ + V(kModuleDeclaration, "Module declaration") \ + V(kModuleLiteral, "Module literal") \ + V(kModulePath, "Module path") \ + V(kModuleStatement, "Module statement") \ + V(kModuleVariable, "Module variable") \ + V(kModuleUrl, "Module url") \ + V(kNativeFunctionLiteral, "Native function literal") \ + V(kSuperReference, "Super reference") \ + V(kNeedSmiLiteral, "Need a Smi literal here") \ + V(kNoCasesLeft, "No cases left") \ + V(kNoEmptyArraysHereInEmitFastAsciiArrayJoin, \ + "No empty arrays here in EmitFastAsciiArrayJoin") \ + V(kNonInitializerAssignmentToConst, "Non-initializer assignment to const") \ + V(kNonSmiIndex, "Non-smi index") \ + V(kNonSmiKeyInArrayLiteral, "Non-smi key in array literal") \ + V(kNonSmiValue, "Non-smi value") \ + V(kNonObject, "Non-object value") \ + V(kNotEnoughVirtualRegistersForValues, \ + "Not enough virtual registers for values") \ + V(kNotEnoughSpillSlotsForOsr, "Not enough spill slots for OSR") \ + V(kNotEnoughVirtualRegistersRegalloc, \ + "Not enough virtual registers (regalloc)") \ + V(kObjectFoundInSmiOnlyArray, "Object found in smi-only array") \ + V(kObjectLiteralWithComplexProperty, "Object literal with complex property") \ + V(kOddballInStringTableIsNotUndefinedOrTheHole, \ + "Oddball in string table is not undefined or the hole") \ + V(kOffsetOutOfRange, "Offset out of range") \ + V(kOperandIsASmiAndNotAName, "Operand is a smi and not a name") \ + V(kOperandIsASmiAndNotAString, "Operand is a smi and not a string") \ + V(kOperandIsASmi, "Operand is a smi") \ + V(kOperandIsNotAName, "Operand is not a name") \ + V(kOperandIsNotANumber, "Operand is not a number") \ + V(kOperandIsNotASmi, "Operand is not a smi") \ + V(kOperandIsNotAString, "Operand is not a string") \ + V(kOperandIsNotSmi, "Operand is not smi") \ + V(kOperandNotANumber, "Operand not a number") \ + V(kObjectTagged, "The object is tagged") \ + V(kObjectNotTagged, "The object is not tagged") \ + V(kOptimizationDisabled, "Optimization is disabled") \ + V(kOptimizedTooManyTimes, "Optimized too many times") \ + V(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister, \ + "Out of virtual registers while trying to allocate temp register") \ + V(kParseScopeError, "Parse/scope error") \ + V(kPossibleDirectCallToEval, "Possible direct call to eval") \ + V(kPreconditionsWereNotMet, "Preconditions were not met") \ + V(kPropertyAllocationCountFailed, "Property allocation count failed") \ + V(kReceivedInvalidReturnAddress, "Received invalid return address") \ + V(kReferenceToAVariableWhichRequiresDynamicLookup, \ + "Reference to a variable which requires dynamic lookup") \ + V(kReferenceToGlobalLexicalVariable, "Reference to global lexical variable") \ + V(kReferenceToUninitializedVariable, "Reference to uninitialized variable") \ + V(kRegisterDidNotMatchExpectedRoot, "Register did not match expected root") \ + V(kRegisterWasClobbered, "Register was clobbered") \ + V(kRememberedSetPointerInNewSpace, "Remembered set pointer is in new space") \ + V(kReturnAddressNotFoundInFrame, "Return address not found in frame") \ + V(kRhsHasBeenClobbered, "Rhs has been clobbered") \ + V(kScopedBlock, "ScopedBlock") \ + V(kSmiAdditionOverflow, "Smi addition overflow") \ + V(kSmiSubtractionOverflow, "Smi subtraction overflow") \ + V(kStackAccessBelowStackPointer, "Stack access below stack pointer") \ + V(kStackFrameTypesMustMatch, "Stack frame types must match") \ + V(kSwitchStatementMixedOrNonLiteralSwitchLabels, \ + "SwitchStatement: mixed or non-literal switch labels") \ + V(kSwitchStatementTooManyClauses, "SwitchStatement: too many clauses") \ + V(kTheCurrentStackPointerIsBelowCsp, \ + "The current stack pointer is below csp") \ + V(kTheInstructionShouldBeALui, "The instruction should be a lui") \ + V(kTheInstructionShouldBeAnOri, "The instruction should be an ori") \ + V(kTheInstructionToPatchShouldBeALoadFromConstantPool, \ + "The instruction to patch should be a load from the constant pool") \ + V(kTheInstructionToPatchShouldBeAnLdrLiteral, \ + "The instruction to patch should be a ldr literal") \ + V(kTheInstructionToPatchShouldBeALui, \ + "The instruction to patch should be a lui") \ + V(kTheInstructionToPatchShouldBeAnOri, \ + "The instruction to patch should be an ori") \ + V(kTheSourceAndDestinationAreTheSame, \ + "The source and destination are the same") \ + V(kTheStackPointerIsNotAligned, "The stack pointer is not aligned.") \ + V(kTheStackWasCorruptedByMacroAssemblerCall, \ + "The stack was corrupted by MacroAssembler::Call()") \ + V(kTooManyParametersLocals, "Too many parameters/locals") \ + V(kTooManyParameters, "Too many parameters") \ + V(kTooManySpillSlotsNeededForOSR, "Too many spill slots needed for OSR") \ + V(kToOperand32UnsupportedImmediate, "ToOperand32 unsupported immediate.") \ + V(kToOperandIsDoubleRegisterUnimplemented, \ + "ToOperand IsDoubleRegister unimplemented") \ + V(kToOperandUnsupportedDoubleImmediate, \ + "ToOperand Unsupported double immediate") \ + V(kTryCatchStatement, "TryCatchStatement") \ + V(kTryFinallyStatement, "TryFinallyStatement") \ + V(kUnableToEncodeValueAsSmi, "Unable to encode value as smi") \ + V(kUnalignedAllocationInNewSpace, "Unaligned allocation in new space") \ + V(kUnalignedCellInWriteBarrier, "Unaligned cell in write barrier") \ + V(kUndefinedValueNotLoaded, "Undefined value not loaded") \ + V(kUndoAllocationOfNonAllocatedMemory, \ + "Undo allocation of non allocated memory") \ + V(kUnexpectedAllocationTop, "Unexpected allocation top") \ + V(kUnexpectedColorFound, "Unexpected color bit pattern found") \ + V(kUnexpectedElementsKindInArrayConstructor, \ + "Unexpected ElementsKind in array constructor") \ + V(kUnexpectedFallthroughFromCharCodeAtSlowCase, \ + "Unexpected fallthrough from CharCodeAt slow case") \ + V(kUnexpectedFallthroughFromCharFromCodeSlowCase, \ + "Unexpected fallthrough from CharFromCode slow case") \ + V(kUnexpectedFallThroughFromStringComparison, \ + "Unexpected fall-through from string comparison") \ + V(kUnexpectedFallThroughInBinaryStubGenerateFloatingPointCode, \ + "Unexpected fall-through in BinaryStub_GenerateFloatingPointCode") \ + V(kUnexpectedFallthroughToCharCodeAtSlowCase, \ + "Unexpected fallthrough to CharCodeAt slow case") \ + V(kUnexpectedFallthroughToCharFromCodeSlowCase, \ + "Unexpected fallthrough to CharFromCode slow case") \ + V(kUnexpectedFPUStackDepthAfterInstruction, \ + "Unexpected FPU stack depth after instruction") \ + V(kUnexpectedInitialMapForArrayFunction1, \ + "Unexpected initial map for Array function (1)") \ + V(kUnexpectedInitialMapForArrayFunction2, \ + "Unexpected initial map for Array function (2)") \ + V(kUnexpectedInitialMapForArrayFunction, \ + "Unexpected initial map for Array function") \ + V(kUnexpectedInitialMapForInternalArrayFunction, \ + "Unexpected initial map for InternalArray function") \ + V(kUnexpectedLevelAfterReturnFromApiCall, \ + "Unexpected level after return from api call") \ + V(kUnexpectedNegativeValue, "Unexpected negative value") \ + V(kUnexpectedNumberOfPreAllocatedPropertyFields, \ + "Unexpected number of pre-allocated property fields") \ + V(kUnexpectedFPCRMode, "Unexpected FPCR mode.") \ + V(kUnexpectedSmi, "Unexpected smi value") \ + V(kUnexpectedStringFunction, "Unexpected String function") \ + V(kUnexpectedStringType, "Unexpected string type") \ + V(kUnexpectedStringWrapperInstanceSize, \ + "Unexpected string wrapper instance size") \ + V(kUnexpectedTypeForRegExpDataFixedArrayExpected, \ + "Unexpected type for RegExp data, FixedArray expected") \ + V(kUnexpectedValue, "Unexpected value") \ + V(kUnexpectedUnusedPropertiesOfStringWrapper, \ + "Unexpected unused properties of string wrapper") \ + V(kUnimplemented, "unimplemented") \ + V(kUninitializedKSmiConstantRegister, "Uninitialized kSmiConstantRegister") \ + V(kUnknown, "Unknown") \ + V(kUnsupportedConstCompoundAssignment, \ + "Unsupported const compound assignment") \ + V(kUnsupportedCountOperationWithConst, \ + "Unsupported count operation with const") \ + V(kUnsupportedDoubleImmediate, "Unsupported double immediate") \ + V(kUnsupportedLetCompoundAssignment, "Unsupported let compound assignment") \ + V(kUnsupportedLookupSlotInDeclaration, \ + "Unsupported lookup slot in declaration") \ + V(kUnsupportedNonPrimitiveCompare, "Unsupported non-primitive compare") \ + V(kUnsupportedPhiUseOfArguments, "Unsupported phi use of arguments") \ + V(kUnsupportedPhiUseOfConstVariable, \ + "Unsupported phi use of const variable") \ + V(kUnsupportedTaggedImmediate, "Unsupported tagged immediate") \ + V(kVariableResolvedToWithContext, "Variable resolved to with context") \ + V(kWeShouldNotHaveAnEmptyLexicalContext, \ + "We should not have an empty lexical context") \ + V(kWithStatement, "WithStatement") \ + V(kWrongFunctionContext, "Wrong context passed to function") \ + V(kWrongAddressOrValuePassedToRecordWrite, \ + "Wrong address or value passed to RecordWrite") \ V(kYield, "Yield") diff --git a/test/cctest/compiler/call-tester.h b/test/cctest/compiler/call-tester.h index 72fafa2..e864160 100644 --- a/test/cctest/compiler/call-tester.h +++ b/test/cctest/compiler/call-tester.h @@ -23,7 +23,7 @@ namespace v8 { namespace internal { namespace compiler { -// TODO(titzer): move MachineType selection for C types into machine-type.h +// TODO(titzer): use c-signature.h instead of ReturnValueTraits template struct ReturnValueTraits { static R Cast(uintptr_t r) { return reinterpret_cast(r); } @@ -130,34 +130,40 @@ struct ParameterTraits { class CallHelper { public: - explicit CallHelper(Isolate* isolate) : isolate_(isolate) { USE(isolate_); } + explicit CallHelper(Isolate* isolate, MachineSignature* machine_sig) + : machine_sig_(machine_sig), isolate_(isolate) { + USE(isolate_); + } virtual ~CallHelper() {} - static MachineCallDescriptorBuilder* ToCallDescriptorBuilder( + static MachineSignature* MakeMachineSignature( Zone* zone, MachineType return_type, MachineType p0 = kMachNone, MachineType p1 = kMachNone, MachineType p2 = kMachNone, MachineType p3 = kMachNone, MachineType p4 = kMachNone) { - const int kSize = 5; - MachineType* params = zone->NewArray(kSize); - params[0] = p0; - params[1] = p1; - params[2] = p2; - params[3] = p3; - params[4] = p4; - int parameter_count = 0; - for (int i = 0; i < kSize; ++i) { - if (params[i] == kMachNone) { - break; - } - parameter_count++; + // Count the number of parameters. + size_t param_count = 5; + MachineType types[] = {p0, p1, p2, p3, p4}; + while (param_count > 0 && types[param_count - 1] == kMachNone) + param_count--; + size_t return_count = return_type == kMachNone ? 0 : 1; + + // Build the machine signature. + MachineSignature::Builder builder(zone, return_count, param_count); + if (return_count > 0) builder.AddReturn(return_type); + for (size_t i = 0; i < param_count; i++) { + builder.AddParam(types[i]); } - return new (zone) - MachineCallDescriptorBuilder(return_type, parameter_count, params); + return builder.Build(); } protected: - virtual void VerifyParameters(int parameter_count, - MachineType* parameters) = 0; + MachineSignature* machine_sig_; + void VerifyParameters(size_t parameter_count, MachineType* parameter_types) { + CHECK(machine_sig_->parameter_count() == parameter_count); + for (size_t i = 0; i < parameter_count; i++) { + CHECK_EQ(machine_sig_->GetParam(i), parameter_types[i]); + } + } virtual byte* Generate() = 0; private: diff --git a/test/cctest/compiler/codegen-tester.h b/test/cctest/compiler/codegen-tester.h index 6c24277..a77df0e 100644 --- a/test/cctest/compiler/codegen-tester.h +++ b/test/cctest/compiler/codegen-tester.h @@ -26,11 +26,13 @@ class MachineAssemblerTester : public HandleAndZoneScope, MachineType p1, MachineType p2, MachineType p3, MachineType p4) : HandleAndZoneScope(), - CallHelper(main_isolate()), - MachineAssembler(new (main_zone()) Graph(main_zone()), - ToCallDescriptorBuilder(main_zone(), return_type, p0, - p1, p2, p3, p4), - kMachPtr) {} + CallHelper( + main_isolate(), + MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4)), + MachineAssembler( + new (main_zone()) Graph(main_zone()), + MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4), + kMachPtr) {} Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) { return this->Load(rep, this->PointerConstant(address), @@ -59,15 +61,6 @@ class MachineAssemblerTester : public HandleAndZoneScope, void GenerateCode() { Generate(); } protected: - virtual void VerifyParameters(int parameter_count, - MachineType* parameter_types) { - CHECK_EQ(this->parameter_count(), parameter_count); - const MachineType* expected_types = this->parameter_types(); - for (int i = 0; i < parameter_count; i++) { - CHECK_EQ(expected_types[i], parameter_types[i]); - } - } - virtual byte* Generate() { if (code_.is_null()) { Schedule* schedule = this->Export(); diff --git a/test/cctest/compiler/graph-builder-tester.cc b/test/cctest/compiler/graph-builder-tester.cc index fb6e4a2..a22e7e1 100644 --- a/test/cctest/compiler/graph-builder-tester.cc +++ b/test/cctest/compiler/graph-builder-tester.cc @@ -9,10 +9,8 @@ namespace v8 { namespace internal { namespace compiler { -MachineCallHelper::MachineCallHelper(Zone* zone, - MachineCallDescriptorBuilder* builder) - : CallHelper(zone->isolate()), - call_descriptor_builder_(builder), +MachineCallHelper::MachineCallHelper(Zone* zone, MachineSignature* machine_sig) + : CallHelper(zone->isolate(), machine_sig), parameters_(NULL), graph_(NULL) {} @@ -21,9 +19,10 @@ void MachineCallHelper::InitParameters(GraphBuilder* builder, CommonOperatorBuilder* common) { DCHECK_EQ(NULL, parameters_); graph_ = builder->graph(); - if (parameter_count() == 0) return; - parameters_ = graph_->zone()->NewArray(parameter_count()); - for (int i = 0; i < parameter_count(); ++i) { + int param_count = static_cast(parameter_count()); + if (param_count == 0) return; + parameters_ = graph_->zone()->NewArray(param_count); + for (int i = 0; i < param_count; ++i) { parameters_[i] = builder->NewNode(common->Parameter(i), graph_->start()); } } @@ -35,7 +34,8 @@ byte* MachineCallHelper::Generate() { if (code_.is_null()) { Zone* zone = graph_->zone(); CompilationInfo info(zone->isolate(), zone); - Linkage linkage(&info, call_descriptor_builder_->BuildCallDescriptor(zone)); + Linkage linkage(&info, + Linkage::GetSimplifiedCDescriptor(zone, machine_sig_)); Pipeline pipeline(&info); code_ = pipeline.GenerateCodeForMachineGraph(&linkage, graph_); } @@ -43,21 +43,10 @@ byte* MachineCallHelper::Generate() { } -void MachineCallHelper::VerifyParameters(int parameter_count, - MachineType* parameter_types) { - CHECK_EQ(this->parameter_count(), parameter_count); - const MachineType* expected_types = - call_descriptor_builder_->parameter_types(); - for (int i = 0; i < parameter_count; i++) { - CHECK_EQ(expected_types[i], parameter_types[i]); - } -} - - -Node* MachineCallHelper::Parameter(int offset) { +Node* MachineCallHelper::Parameter(size_t index) { DCHECK_NE(NULL, parameters_); - DCHECK(0 <= offset && offset < parameter_count()); - return parameters_[offset]; + DCHECK(index < parameter_count()); + return parameters_[index]; } } // namespace compiler diff --git a/test/cctest/compiler/graph-builder-tester.h b/test/cctest/compiler/graph-builder-tester.h index 5f0d825..32f0306 100644 --- a/test/cctest/compiler/graph-builder-tester.h +++ b/test/cctest/compiler/graph-builder-tester.h @@ -37,24 +37,20 @@ class DirectGraphBuilder : public GraphBuilder { class MachineCallHelper : public CallHelper { public: - MachineCallHelper(Zone* zone, MachineCallDescriptorBuilder* builder); + MachineCallHelper(Zone* zone, MachineSignature* machine_sig); - Node* Parameter(int offset); + Node* Parameter(size_t index); void GenerateCode() { Generate(); } protected: virtual byte* Generate(); - virtual void VerifyParameters(int parameter_count, MachineType* parameters); void InitParameters(GraphBuilder* builder, CommonOperatorBuilder* common); protected: - int parameter_count() const { - return call_descriptor_builder_->parameter_count(); - } + size_t parameter_count() const { return machine_sig_->parameter_count(); } private: - MachineCallDescriptorBuilder* call_descriptor_builder_; Node** parameters_; // TODO(dcarney): shouldn't need graph stored. Graph* graph_; @@ -95,12 +91,12 @@ class GraphBuilderTester : GraphAndBuilders(main_zone()), MachineCallHelper( main_zone(), - ToCallDescriptorBuilder( + MakeMachineSignature( main_zone(), ReturnValueTraits::Representation(), p0, p1, p2, p3, p4)), SimplifiedGraphBuilder(main_graph_, &main_common_, &main_machine_, &main_simplified_) { - Begin(parameter_count()); + Begin(static_cast(parameter_count())); InitParameters(this, &main_common_); } virtual ~GraphBuilderTester() {} diff --git a/test/cctest/compiler/test-codegen-deopt.cc b/test/cctest/compiler/test-codegen-deopt.cc index e11fc55..21766e8 100644 --- a/test/cctest/compiler/test-codegen-deopt.cc +++ b/test/cctest/compiler/test-codegen-deopt.cc @@ -20,6 +20,7 @@ #include "src/parser.h" #include "src/rewriter.h" +#include "test/cctest/compiler/c-signature.h" #include "test/cctest/compiler/function-tester.h" using namespace v8::internal; @@ -64,7 +65,9 @@ class DeoptCodegenTester { void GenerateCodeFromSchedule(Schedule* schedule) { OFStream os(stdout); - os << *schedule; + if (FLAG_trace_turbo) { + os << *schedule; + } // Initialize the codegen and generate code. Linkage* linkage = new (scope_->main_zone()) Linkage(&info); @@ -74,20 +77,26 @@ class DeoptCodegenTester { InstructionSelector selector(code, &source_positions); selector.SelectInstructions(); - os << "----- Instruction sequence before register allocation -----\n" - << *code; + if (FLAG_trace_turbo) { + os << "----- Instruction sequence before register allocation -----\n" + << *code; + } RegisterAllocator allocator(code); CHECK(allocator.Allocate()); - os << "----- Instruction sequence after register allocation -----\n" - << *code; + if (FLAG_trace_turbo) { + os << "----- Instruction sequence after register allocation -----\n" + << *code; + } compiler::CodeGenerator generator(code); result_code = generator.GenerateCode(); -#ifdef DEBUG - result_code->Print(); +#ifdef OBJECT_PRINT + if (FLAG_print_opt_code || FLAG_trace_turbo) { + result_code->Print(); + } #endif } @@ -122,11 +131,8 @@ class TrivialDeoptCodegenTester : public DeoptCodegenTester { // deopt(); // } - MachineType parameter_reps[] = {kMachAnyTagged}; - MachineCallDescriptorBuilder descriptor_builder(kMachAnyTagged, 1, - parameter_reps); - - RawMachineAssembler m(graph, &descriptor_builder); + CSignature1 sig; + RawMachineAssembler m(graph, &sig); Handle undef_object = Handle(isolate->heap()->undefined_value(), isolate); @@ -140,6 +146,10 @@ class TrivialDeoptCodegenTester : public DeoptCodegenTester { PrintableUnique::CreateUninitialized(zone(), deopt_function); Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant)); + Handle context(deopt_function->context(), isolate); + PrintableUnique context_constant = + PrintableUnique::CreateUninitialized(zone(), context); + Node* context_node = m.NewNode(common.HeapConstant(context_constant)); bailout_id = GetCallBailoutId(); Node* parameters = m.NewNode(common.StateValues(1), undef_node); @@ -149,7 +159,7 @@ class TrivialDeoptCodegenTester : public DeoptCodegenTester { Node* state_node = m.NewNode(common.FrameState(bailout_id, kIgnoreOutput), parameters, locals, stack, undef_node); - m.CallJS0(deopt_fun_node, undef_node, state_node); + m.CallJS0(deopt_fun_node, undef_node, context_node, state_node); m.Return(undef_node); @@ -238,11 +248,8 @@ class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester { // %DeoptimizeFunction(foo); // } - MachineType parameter_reps[] = {kMachAnyTagged}; - MachineCallDescriptorBuilder descriptor_builder(kMachAnyTagged, 2, - parameter_reps); - - RawMachineAssembler m(graph, &descriptor_builder); + CSignature1 sig; + RawMachineAssembler m(graph, &sig); Handle undef_object = Handle(isolate->heap()->undefined_value(), isolate); @@ -254,6 +261,11 @@ class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester { PrintableUnique::CreateUninitialized(zone(), function); Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant)); + Handle context(function->context(), isolate); + PrintableUnique context_constant = + PrintableUnique::CreateUninitialized(zone(), context); + Node* context_node = m.NewNode(common.HeapConstant(context_constant)); + bailout_id = GetCallBailoutId(); Node* parameters = m.NewNode(common.StateValues(1), undef_node); Node* locals = m.NewNode(common.StateValues(0)); @@ -262,7 +274,8 @@ class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester { Node* state_node = m.NewNode(common.FrameState(bailout_id, kIgnoreOutput), parameters, locals, stack, undef_node); - m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, state_node); + m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, context_node, + state_node); m.Return(undef_node); diff --git a/test/cctest/compiler/test-linkage.cc b/test/cctest/compiler/test-linkage.cc index 6d9453f..ff65d6e 100644 --- a/test/cctest/compiler/test-linkage.cc +++ b/test/cctest/compiler/test-linkage.cc @@ -65,7 +65,7 @@ TEST(TestLinkageJSFunctionIncoming) { CallDescriptor* descriptor = linkage.GetIncomingDescriptor(); CHECK_NE(NULL, descriptor); - CHECK_EQ(1 + i, descriptor->ParameterCount()); + CHECK_EQ(1 + i, descriptor->JSParameterCount()); CHECK_EQ(1, descriptor->ReturnCount()); CHECK_EQ(Operator::kNoProperties, descriptor->properties()); CHECK_EQ(true, descriptor->IsJSFunctionCall()); @@ -92,7 +92,7 @@ TEST(TestLinkageJSCall) { for (int i = 0; i < 32; i++) { CallDescriptor* descriptor = linkage.GetJSCallDescriptor(i); CHECK_NE(NULL, descriptor); - CHECK_EQ(i, descriptor->ParameterCount()); + CHECK_EQ(i, descriptor->JSParameterCount()); CHECK_EQ(1, descriptor->ReturnCount()); CHECK_EQ(Operator::kNoProperties, descriptor->properties()); CHECK_EQ(true, descriptor->IsJSFunctionCall()); -- 2.7.4