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);
__ Ret();
} else {
__ LeaveFrame(StackFrame::MANUAL);
- int pop_count =
- descriptor->IsJSFunctionCall() ? descriptor->ParameterCount() : 0;
+ int pop_count = descriptor->IsJSFunctionCall()
+ ? static_cast<int>(descriptor->JSParameterCount())
+ : 0;
__ Drop(pop_count);
__ Ret();
}
namespace internal {
namespace compiler {
-struct LinkageHelperTraits {
+struct ArmLinkageHelperTraits {
static Register ReturnValueReg() { return r0; }
static Register ReturnValue2Reg() { return r1; }
static Register JSCallFunctionReg() { return r1; }
};
+typedef LinkageHelper<ArmLinkageHelperTraits> LH;
+
CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) {
- return LinkageHelper::GetJSCallDescriptor<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- zone, num_params, return_type, param_types);
+CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
+ MachineSignature* sig) {
+ return LH::GetSimplifiedCDescriptor(zone, sig);
}
} // namespace compiler
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);
} else {
__ Mov(jssp, fp);
__ Pop(fp, lr);
- int pop_count =
- descriptor->IsJSFunctionCall() ? descriptor->ParameterCount() : 0;
+ int pop_count = descriptor->IsJSFunctionCall()
+ ? static_cast<int>(descriptor->JSParameterCount())
+ : 0;
__ Drop(pop_count);
__ Ret();
}
namespace internal {
namespace compiler {
-struct LinkageHelperTraits {
+struct Arm64LinkageHelperTraits {
static Register ReturnValueReg() { return x0; }
static Register ReturnValue2Reg() { return x1; }
static Register JSCallFunctionReg() { return x1; }
};
+typedef LinkageHelper<Arm64LinkageHelperTraits> LH;
+
CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) {
- return LinkageHelper::GetJSCallDescriptor<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- zone, num_params, return_type, param_types);
+CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
+ MachineSignature* sig) {
+ return LH::GetSimplifiedCDescriptor(zone, sig);
}
} // namespace compiler
class CallOperator FINAL : public Operator1<CallDescriptor*> {
public:
+ // TODO(titzer): Operator still uses int, whereas CallDescriptor uses size_t.
CallOperator(CallDescriptor* descriptor, const char* mnemonic)
: Operator1<CallDescriptor*>(
IrOpcode::kCall, descriptor->properties(),
- descriptor->InputCount() + descriptor->FrameStateCount(),
- descriptor->ReturnCount(), mnemonic, descriptor) {}
+ static_cast<int>(descriptor->InputCount() +
+ descriptor->FrameStateCount()),
+ static_cast<int>(descriptor->ReturnCount()), mnemonic, descriptor) {
+ }
virtual OStream& PrintParameter(OStream& os) const OVERRIDE { // NOLINT
return os << "[" << *parameter() << "]";
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<GraphDecorator*>::iterator i = decorators_.begin();
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;
} 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<int>(descriptor->JSParameterCount())
+ : 0;
__ ret(pop_count * kPointerSize);
}
}
namespace internal {
namespace compiler {
-struct LinkageHelperTraits {
+struct IA32LinkageHelperTraits {
static Register ReturnValueReg() { return eax; }
static Register ReturnValue2Reg() { return edx; }
static Register JSCallFunctionReg() { return edi; }
static int CRegisterParametersLength() { return 0; }
};
+typedef LinkageHelper<IA32LinkageHelperTraits> LH;
CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) {
- return LinkageHelper::GetJSCallDescriptor<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- zone, num_params, return_type, param_types);
+CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
+ MachineSignature* sig) {
+ return LH::GetSimplifiedCDescriptor(zone, sig);
}
} // namespace compiler
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) {
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() {
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);
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_);
}
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);
// -----------------------------------------------------------------------------
// 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));
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);
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) {
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<MachineType>(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<MachineType>(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<MachineType>(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:
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<int>(i));
LinkageLocation location =
buffer->descriptor->GetReturnLocation(static_cast<int>(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));
}
}
}
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());
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<int>(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<size_t>(buffer->input_count());
// Split the arguments into pushed_nodes and instruction_args. Pushed
// arguments require an explicit push instruction before the call and do
// 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<size_t>(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<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
case IrOpcode::kFinish:
return MarkAsReference(node), VisitFinish(node);
case IrOpcode::kParameter: {
- LinkageLocation location =
- linkage()->GetParameterLocation(OpParameter<int>(node));
- MarkAsRepresentation(location.representation(), node);
+ MachineType type = linkage()->GetParameterType(OpParameter<int>(node));
+ MarkAsRepresentation(type, node);
return VisitParameter(node);
}
case IrOpcode::kPhi:
void InstructionSelector::VisitParameter(Node* node) {
OperandGenerator g(this);
- Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetParameterLocation(
- OpParameter<int>(node))));
+ int index = OpParameter<int>(node);
+ Emit(kArchNop,
+ g.DefineAsLocation(node, linkage()->GetParameterLocation(index),
+ linkage()->GetParameterType(index)));
}
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);
}
namespace internal {
namespace compiler {
+// TODO(titzer): replace uses of int with size_t in LinkageHelper.
+template <typename LinkageTraits>
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 <typename LinkageTraits>
- 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<LinkageLocation>(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 <typename LinkageTraits>
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<size_t>(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<LinkageLocation>(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<size_t>(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 <typename LinkageTraits>
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<size_t>(js_parameter_count + context_count);
- const int return_count = 1;
- LinkageLocation* locations =
- zone->NewArray<LinkageLocation>(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 <typename LinkageTraits>
- static CallDescriptor* GetSimplifiedCDescriptor(
- Zone* zone, int num_params, MachineType return_type,
- const MachineType* param_types) {
- LinkageLocation* locations =
- zone->NewArray<LinkageLocation>(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<int>(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
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();
}
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<LinkageLocation> 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.
};
typedef base::Flags<Flag> 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_; }
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_;
// 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.
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
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<NodeFactory*>(this)->zone()
#define COMMON() static_cast<NodeFactory*>(this)->common()
#define MACHINE() static_cast<NodeFactory*>(this)->machine()
+#define MACHINE_SIG() static_cast<NodeFactory*>(this)->machine_sig()
#define NEW_NODE_0(op) static_cast<NodeFactory*>(this)->NewNode(op)
#define NEW_NODE_1(op, a) static_cast<NodeFactory*>(this)->NewNode(op, a)
#define NEW_NODE_2(op, a, b) static_cast<NodeFactory*>(this)->NewNode(op, a, b)
// 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<Node**>(alloca((n_args + 1) * sizeof(args[0])));
passed_args[0] = function_address;
#include "src/base/bits.h"
#include "src/globals.h"
+#include "src/zone.h"
namespace v8 {
namespace internal {
}
}
-// 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 <typename T>
+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<T>(
+ static_cast<int>(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<T>* Build() {
+ DCHECK(rcursor_ == return_count_);
+ DCHECK(pcursor_ == parameter_count_);
+ return new (zone_) Signature<T>(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<MachineType> MachineSignature;
} // namespace compiler
} // namespace internal
} // 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<int>(parameter_count());
+ Node* s = graph->NewNode(common_.Start(param_count));
graph->SetStart(s);
if (parameter_count() == 0) return;
- parameters_ = zone()->NewArray<Node*>(parameter_count());
- for (int i = 0; i < parameter_count(); ++i) {
- parameters_[i] = NewNode(common()->Parameter(i), graph->start());
+ parameters_ = zone()->NewArray<Node*>(param_count);
+ for (size_t i = 0; i < parameter_count(); ++i) {
+ parameters_[i] =
+ NewNode(common()->Parameter(static_cast<int>(i)), graph->start());
}
}
}
-Node* RawMachineAssembler::Parameter(int index) {
- DCHECK(0 <= index && index < parameter_count());
+Node* RawMachineAssembler::Parameter(size_t index) {
+ DCHECK(index < parameter_count());
return parameters_[index];
}
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());
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);
DISALLOW_COPY_AND_ASSIGN(Label);
};
- RawMachineAssembler(Graph* graph,
- MachineCallDescriptorBuilder* call_descriptor_builder,
+ RawMachineAssembler(Graph* graph, MachineSignature* machine_sig,
MachineType word = kMachPtr);
virtual ~RawMachineAssembler() {}
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();
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);
Schedule* schedule_;
MachineOperatorBuilder machine_;
CommonOperatorBuilder common_;
- MachineCallDescriptorBuilder* call_descriptor_builder_;
+ MachineSignature* machine_sig_;
+ CallDescriptor* call_descriptor_;
Node** parameters_;
Label exit_label_;
BasicBlock* current_block_;
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<int>(parameter_count());
+ Node* s = graph->NewNode(common_.Start(param_count));
graph->SetStart(s);
if (parameter_count() == 0) return;
- parameters_ = zone()->NewArray<Node*>(parameter_count());
- for (int i = 0; i < parameter_count(); ++i) {
- parameters_[i] = NewNode(common()->Parameter(i), graph->start());
+ parameters_ = zone()->NewArray<Node*>(param_count);
+ for (size_t i = 0; i < parameter_count(); ++i) {
+ parameters_[i] =
+ NewNode(common()->Parameter(static_cast<int>(i)), graph->start());
}
}
}
-Node* StructuredMachineAssembler::Parameter(int index) {
- DCHECK(0 <= index && index < parameter_count());
+Node* StructuredMachineAssembler::Parameter(size_t index) {
+ DCHECK(index < parameter_count());
return parameters_[index];
}
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.
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_;
}
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;
} 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<int>(descriptor->JSParameterCount())
+ : 0;
__ ret(pop_count * kPointerSize);
}
}
FrameStateDescriptor* frame_state_descriptor = NULL;
if (descriptor->NeedsFrameState()) {
- frame_state_descriptor =
- GetFrameStateDescriptor(call->InputAt(descriptor->InputCount()));
+ frame_state_descriptor = GetFrameStateDescriptor(
+ call->InputAt(static_cast<int>(descriptor->InputCount())));
}
CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
const bool kWin64 = false;
#endif
-struct LinkageHelperTraits {
+struct X64LinkageHelperTraits {
static Register ReturnValueReg() { return rax; }
static Register ReturnValue2Reg() { return rdx; }
static Register JSCallFunctionReg() { return rdi; }
static int CRegisterParametersLength() { return kWin64 ? 4 : 6; }
};
+typedef LinkageHelper<X64LinkageHelperTraits> LH;
CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) {
- return LinkageHelper::GetJSCallDescriptor<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- 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<LinkageHelperTraits>(
- zone, num_params, return_type, param_types);
+CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
+ MachineSignature* sig) {
+ return LH::GetSimplifiedCDescriptor(zone, sig);
}
} // namespace compiler
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")
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 <typename R>
struct ReturnValueTraits {
static R Cast(uintptr_t r) { return reinterpret_cast<R>(r); }
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<MachineType>(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:
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),
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();
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) {}
CommonOperatorBuilder* common) {
DCHECK_EQ(NULL, parameters_);
graph_ = builder->graph();
- if (parameter_count() == 0) return;
- parameters_ = graph_->zone()->NewArray<Node*>(parameter_count());
- for (int i = 0; i < parameter_count(); ++i) {
+ int param_count = static_cast<int>(parameter_count());
+ if (param_count == 0) return;
+ parameters_ = graph_->zone()->NewArray<Node*>(param_count);
+ for (int i = 0; i < param_count; ++i) {
parameters_[i] = builder->NewNode(common->Parameter(i), graph_->start());
}
}
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_);
}
}
-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
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_;
: GraphAndBuilders(main_zone()),
MachineCallHelper(
main_zone(),
- ToCallDescriptorBuilder(
+ MakeMachineSignature(
main_zone(), ReturnValueTraits<ReturnType>::Representation(),
p0, p1, p2, p3, p4)),
SimplifiedGraphBuilder(main_graph_, &main_common_, &main_machine_,
&main_simplified_) {
- Begin(parameter_count());
+ Begin(static_cast<int>(parameter_count()));
InitParameters(this, &main_common_);
}
virtual ~GraphBuilderTester() {}
#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;
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);
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
}
// deopt();
// }
- MachineType parameter_reps[] = {kMachAnyTagged};
- MachineCallDescriptorBuilder descriptor_builder(kMachAnyTagged, 1,
- parameter_reps);
-
- RawMachineAssembler m(graph, &descriptor_builder);
+ CSignature1<Object*, Object*> sig;
+ RawMachineAssembler m(graph, &sig);
Handle<Object> undef_object =
Handle<Object>(isolate->heap()->undefined_value(), isolate);
PrintableUnique<Object>::CreateUninitialized(zone(), deopt_function);
Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));
+ Handle<Context> context(deopt_function->context(), isolate);
+ PrintableUnique<Object> context_constant =
+ PrintableUnique<Object>::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* 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);
// %DeoptimizeFunction(foo);
// }
- MachineType parameter_reps[] = {kMachAnyTagged};
- MachineCallDescriptorBuilder descriptor_builder(kMachAnyTagged, 2,
- parameter_reps);
-
- RawMachineAssembler m(graph, &descriptor_builder);
+ CSignature1<Object*, Object*> sig;
+ RawMachineAssembler m(graph, &sig);
Handle<Object> undef_object =
Handle<Object>(isolate->heap()->undefined_value(), isolate);
PrintableUnique<Object>::CreateUninitialized(zone(), function);
Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant));
+ Handle<Context> context(function->context(), isolate);
+ PrintableUnique<Object> context_constant =
+ PrintableUnique<Object>::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));
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);
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());
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());