Commit 905e008c authored by mvstanton's avatar mvstanton Committed by Commit bot

Vector ICs: Hook up vectors in platform builtins to their SharedFunctionInfos.

BUG=v8:4423
LOG=N

Review URL: https://codereview.chromium.org/1342013003

Cr-Commit-Position: refs/heads/master@{#30758}
parent bf68348d
...@@ -1255,6 +1255,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -1255,6 +1255,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
static void Generate_PushAppliedArguments(MacroAssembler* masm, static void Generate_PushAppliedArguments(MacroAssembler* masm,
const int vectorOffset,
const int argumentsOffset, const int argumentsOffset,
const int indexOffset, const int indexOffset,
const int limitOffset) { const int limitOffset) {
...@@ -1272,13 +1273,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm, ...@@ -1272,13 +1273,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm,
__ ldr(receiver, MemOperand(fp, argumentsOffset)); __ ldr(receiver, MemOperand(fp, argumentsOffset));
// Use inline caching to speed up access to arguments. // Use inline caching to speed up access to arguments.
Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex();
FeedbackVectorSpec spec(0, 1, kinds); __ mov(slot, Operand(Smi::FromInt(slot_index)));
Handle<TypeFeedbackVector> feedback_vector = __ ldr(vector, MemOperand(fp, vectorOffset));
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
__ mov(slot, Operand(Smi::FromInt(index)));
__ Move(vector, feedback_vector);
Handle<Code> ic = Handle<Code> ic =
KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
...@@ -1313,6 +1310,13 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1313,6 +1310,13 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
const int kReceiverOffset = kArgumentsOffset + kPointerSize; const int kReceiverOffset = kArgumentsOffset + kPointerSize;
const int kFunctionOffset = kReceiverOffset + kPointerSize; const int kFunctionOffset = kReceiverOffset + kPointerSize;
const int kVectorOffset =
InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
// Push the vector.
__ ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kFeedbackVectorOffset));
__ Push(r1);
__ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function
__ ldr(r1, MemOperand(fp, kArgumentsOffset)); // get the args array __ ldr(r1, MemOperand(fp, kArgumentsOffset)); // get the args array
...@@ -1327,17 +1331,15 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1327,17 +1331,15 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged); Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged);
// Push current limit and index. // Push current limit and index.
const int kIndexOffset = const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
const int kLimitOffset =
StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
__ mov(r1, Operand::Zero()); __ mov(r1, Operand::Zero());
__ ldr(r2, MemOperand(fp, kReceiverOffset)); __ ldr(r2, MemOperand(fp, kReceiverOffset));
__ Push(r0, r1, r2); // limit, initial index and receiver. __ Push(r0, r1, r2); // limit, initial index and receiver.
// Copy all arguments from the array to the stack. // Copy all arguments from the array to the stack.
Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset, Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
kLimitOffset); kIndexOffset, kLimitOffset);
// Call the callable. // Call the callable.
// TODO(bmeurer): This should be a tail call according to ES6. // TODO(bmeurer): This should be a tail call according to ES6.
...@@ -1360,6 +1362,13 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1360,6 +1362,13 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
const int kArgumentsOffset = kNewTargetOffset + kPointerSize; const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
const int kFunctionOffset = kArgumentsOffset + kPointerSize; const int kFunctionOffset = kArgumentsOffset + kPointerSize;
static const int kVectorOffset =
InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
// Push the vector.
__ ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kFeedbackVectorOffset));
__ Push(r1);
// If newTarget is not supplied, set it to constructor // If newTarget is not supplied, set it to constructor
Label validate_arguments; Label validate_arguments;
...@@ -1383,10 +1392,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1383,10 +1392,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged); Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged);
// Push current limit and index. // Push current limit and index.
const int kIndexOffset = const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
const int kLimitOffset =
StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
__ push(r0); // limit __ push(r0); // limit
__ mov(r1, Operand::Zero()); // initial index __ mov(r1, Operand::Zero()); // initial index
__ push(r1); __ push(r1);
...@@ -1395,8 +1402,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1395,8 +1402,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
__ push(r0); __ push(r0);
// Copy all arguments from the array to the stack. // Copy all arguments from the array to the stack.
Generate_PushAppliedArguments( Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
masm, kArgumentsOffset, kIndexOffset, kLimitOffset); kIndexOffset, kLimitOffset);
// Use undefined feedback vector // Use undefined feedback vector
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex); __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
......
...@@ -1290,6 +1290,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -1290,6 +1290,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
static void Generate_PushAppliedArguments(MacroAssembler* masm, static void Generate_PushAppliedArguments(MacroAssembler* masm,
const int vectorOffset,
const int argumentsOffset, const int argumentsOffset,
const int indexOffset, const int indexOffset,
const int limitOffset) { const int limitOffset) {
...@@ -1307,13 +1308,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm, ...@@ -1307,13 +1308,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm,
__ Ldr(receiver, MemOperand(fp, argumentsOffset)); __ Ldr(receiver, MemOperand(fp, argumentsOffset));
// Use inline caching to speed up access to arguments. // Use inline caching to speed up access to arguments.
Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex();
FeedbackVectorSpec spec(0, 1, kinds); __ Mov(slot, Operand(Smi::FromInt(slot_index)));
Handle<TypeFeedbackVector> feedback_vector = __ Ldr(vector, MemOperand(fp, vectorOffset));
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
__ Mov(slot, Smi::FromInt(index));
__ Mov(vector, feedback_vector);
Handle<Code> ic = Handle<Code> ic =
KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
...@@ -1348,14 +1345,24 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1348,14 +1345,24 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
const int kReceiverOffset = kArgumentsOffset + kPointerSize; const int kReceiverOffset = kArgumentsOffset + kPointerSize;
const int kFunctionOffset = kReceiverOffset + kPointerSize; const int kFunctionOffset = kReceiverOffset + kPointerSize;
const int kIndexOffset = const int kVectorOffset =
StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
const int kLimitOffset = const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
Register args = x12; Register args = x12;
Register receiver = x14; Register receiver = x14;
Register function = x15; Register function = x15;
Register apply_function = x1;
// Push the vector.
__ Ldr(
apply_function,
FieldMemOperand(apply_function, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(apply_function,
FieldMemOperand(apply_function,
SharedFunctionInfo::kFeedbackVectorOffset));
__ Push(apply_function);
// Get the length of the arguments via a builtin call. // Get the length of the arguments via a builtin call.
__ Ldr(function, MemOperand(fp, kFunctionOffset)); __ Ldr(function, MemOperand(fp, kFunctionOffset));
...@@ -1377,8 +1384,8 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1377,8 +1384,8 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
__ Push(argc, x1, receiver); __ Push(argc, x1, receiver);
// Copy all arguments from the array to the stack. // Copy all arguments from the array to the stack.
Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset, Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
kLimitOffset); kIndexOffset, kLimitOffset);
// At the end of the loop, the number of arguments is stored in x0, untagged // At the end of the loop, the number of arguments is stored in x0, untagged
...@@ -1402,16 +1409,25 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1402,16 +1409,25 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
const int kArgumentsOffset = kNewTargetOffset + kPointerSize; const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
const int kFunctionOffset = kArgumentsOffset + kPointerSize; const int kFunctionOffset = kArgumentsOffset + kPointerSize;
const int kVectorOffset =
const int kIndexOffset = InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
const int kLimitOffset = const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
// Is x11 safe to use? // Is x11 safe to use?
Register newTarget = x11; Register newTarget = x11;
Register args = x12; Register args = x12;
Register function = x15; Register function = x15;
Register construct_function = x1;
// Push the vector.
__ Ldr(construct_function,
FieldMemOperand(construct_function,
JSFunction::kSharedFunctionInfoOffset));
__ Ldr(construct_function,
FieldMemOperand(construct_function,
SharedFunctionInfo::kFeedbackVectorOffset));
__ Push(construct_function);
// If newTarget is not supplied, set it to constructor // If newTarget is not supplied, set it to constructor
Label validate_arguments; Label validate_arguments;
...@@ -1438,8 +1454,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1438,8 +1454,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
__ Push(argc, x1, function); __ Push(argc, x1, function);
// Copy all arguments from the array to the stack. // Copy all arguments from the array to the stack.
Generate_PushAppliedArguments( Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
masm, kArgumentsOffset, kIndexOffset, kLimitOffset); kIndexOffset, kLimitOffset);
// Use undefined feedback vector // Use undefined feedback vector
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex); __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
......
...@@ -1796,6 +1796,8 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate, ...@@ -1796,6 +1796,8 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
MaybeHandle<JSObject>(), Builtins::kReflectApply); MaybeHandle<JSObject>(), Builtins::kReflectApply);
apply->shared()->set_internal_formal_parameter_count(3); apply->shared()->set_internal_formal_parameter_count(3);
apply->shared()->set_length(3); apply->shared()->set_length(3);
apply->shared()->set_feedback_vector(
*TypeFeedbackVector::CreatePushAppliedArgumentsVector(isolate));
isolate->native_context()->set_reflect_apply(*apply); isolate->native_context()->set_reflect_apply(*apply);
Handle<JSFunction> construct = InstallFunction( Handle<JSFunction> construct = InstallFunction(
...@@ -1803,6 +1805,8 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate, ...@@ -1803,6 +1805,8 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
MaybeHandle<JSObject>(), Builtins::kReflectConstruct); MaybeHandle<JSObject>(), Builtins::kReflectConstruct);
construct->shared()->set_internal_formal_parameter_count(3); construct->shared()->set_internal_formal_parameter_count(3);
construct->shared()->set_length(2); construct->shared()->set_length(2);
construct->shared()->set_feedback_vector(
*TypeFeedbackVector::CreatePushAppliedArgumentsVector(isolate));
isolate->native_context()->set_reflect_construct(*construct); isolate->native_context()->set_reflect_construct(*construct);
} }
...@@ -2381,6 +2385,8 @@ bool Genesis::InstallNatives(ContextType context_type) { ...@@ -2381,6 +2385,8 @@ bool Genesis::InstallNatives(ContextType context_type) {
Handle<JSFunction> apply = Handle<JSFunction> apply =
InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize, InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
MaybeHandle<JSObject>(), Builtins::kFunctionApply); MaybeHandle<JSObject>(), Builtins::kFunctionApply);
apply->shared()->set_feedback_vector(
*TypeFeedbackVector::CreatePushAppliedArgumentsVector(isolate()));
// Make sure that Function.prototype.call appears to be compiled. // Make sure that Function.prototype.call appears to be compiled.
// The code will never be called, but inline caching for call will // The code will never be called, but inline caching for call will
......
...@@ -1004,6 +1004,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -1004,6 +1004,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
static void Generate_PushAppliedArguments(MacroAssembler* masm, static void Generate_PushAppliedArguments(MacroAssembler* masm,
const int vectorOffset,
const int argumentsOffset, const int argumentsOffset,
const int indexOffset, const int indexOffset,
const int limitOffset) { const int limitOffset) {
...@@ -1019,13 +1020,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm, ...@@ -1019,13 +1020,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm,
__ mov(receiver, Operand(ebp, argumentsOffset)); // load arguments __ mov(receiver, Operand(ebp, argumentsOffset)); // load arguments
// Use inline caching to speed up access to arguments. // Use inline caching to speed up access to arguments.
Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex();
FeedbackVectorSpec spec(0, 1, kinds); __ mov(slot, Immediate(Smi::FromInt(slot_index)));
Handle<TypeFeedbackVector> feedback_vector = __ mov(vector, Operand(ebp, vectorOffset));
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
__ mov(slot, Immediate(Smi::FromInt(index)));
__ mov(vector, Immediate(feedback_vector));
Handle<Code> ic = Handle<Code> ic =
KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
__ call(ic, RelocInfo::CODE_TARGET); __ call(ic, RelocInfo::CODE_TARGET);
...@@ -1073,6 +1070,13 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1073,6 +1070,13 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
static const int kReceiverOffset = kArgumentsOffset + kPointerSize; static const int kReceiverOffset = kArgumentsOffset + kPointerSize;
static const int kFunctionOffset = kReceiverOffset + kPointerSize; static const int kFunctionOffset = kReceiverOffset + kPointerSize;
static const int kVectorOffset =
InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
// Push the vector.
__ mov(edi, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ mov(edi, FieldOperand(edi, SharedFunctionInfo::kFeedbackVectorOffset));
__ push(edi);
__ push(Operand(ebp, kFunctionOffset)); // push this __ push(Operand(ebp, kFunctionOffset)); // push this
__ push(Operand(ebp, kArgumentsOffset)); // push arguments __ push(Operand(ebp, kArgumentsOffset)); // push arguments
...@@ -1086,16 +1090,15 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1086,16 +1090,15 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged);
// Push current index and limit. // Push current index and limit.
const int kLimitOffset = const int kLimitOffset = kVectorOffset - 1 * kPointerSize;
StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
const int kIndexOffset = kLimitOffset - 1 * kPointerSize; const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
__ Push(eax); // limit __ Push(eax); // limit
__ Push(Immediate(0)); // index __ Push(Immediate(0)); // index
__ Push(Operand(ebp, kReceiverOffset)); // receiver __ Push(Operand(ebp, kReceiverOffset)); // receiver
// Loop over the arguments array, pushing each value to the stack // Loop over the arguments array, pushing each value to the stack
Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset, Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
kLimitOffset); kIndexOffset, kLimitOffset);
// Call the callable. // Call the callable.
// TODO(bmeurer): This should be a tail call according to ES6. // TODO(bmeurer): This should be a tail call according to ES6.
...@@ -1129,6 +1132,13 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1129,6 +1132,13 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; static const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
static const int kFunctionOffset = kArgumentsOffset + kPointerSize; static const int kFunctionOffset = kArgumentsOffset + kPointerSize;
static const int kVectorOffset =
InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
// Push the vector.
__ mov(edi, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ mov(edi, FieldOperand(edi, SharedFunctionInfo::kFeedbackVectorOffset));
__ push(edi);
// If newTarget is not supplied, set it to constructor // If newTarget is not supplied, set it to constructor
Label validate_arguments; Label validate_arguments;
...@@ -1149,8 +1159,7 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1149,8 +1159,7 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged);
// Push current index and limit. // Push current index and limit.
const int kLimitOffset = const int kLimitOffset = kVectorOffset - 1 * kPointerSize;
StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
const int kIndexOffset = kLimitOffset - 1 * kPointerSize; const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
__ Push(eax); // limit __ Push(eax); // limit
__ push(Immediate(0)); // index __ push(Immediate(0)); // index
...@@ -1158,8 +1167,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1158,8 +1167,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
__ push(Operand(ebp, kFunctionOffset)); __ push(Operand(ebp, kFunctionOffset));
// Loop over the arguments array, pushing each value to the stack // Loop over the arguments array, pushing each value to the stack
Generate_PushAppliedArguments( Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
masm, kArgumentsOffset, kIndexOffset, kLimitOffset); kIndexOffset, kLimitOffset);
// Use undefined feedback vector // Use undefined feedback vector
__ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex);
......
...@@ -1253,6 +1253,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -1253,6 +1253,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
static void Generate_PushAppliedArguments(MacroAssembler* masm, static void Generate_PushAppliedArguments(MacroAssembler* masm,
const int vectorOffset,
const int argumentsOffset, const int argumentsOffset,
const int indexOffset, const int indexOffset,
const int limitOffset) { const int limitOffset) {
...@@ -1270,13 +1271,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm, ...@@ -1270,13 +1271,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm,
__ lw(receiver, MemOperand(fp, argumentsOffset)); __ lw(receiver, MemOperand(fp, argumentsOffset));
// Use inline caching to speed up access to arguments. // Use inline caching to speed up access to arguments.
Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex();
FeedbackVectorSpec spec(0, 1, kinds); __ li(slot, Operand(Smi::FromInt(slot_index)));
Handle<TypeFeedbackVector> feedback_vector = __ lw(vector, MemOperand(fp, vectorOffset));
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
__ li(slot, Operand(Smi::FromInt(index)));
__ li(vector, feedback_vector);
Handle<Code> ic = Handle<Code> ic =
KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
...@@ -1310,6 +1307,13 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1310,6 +1307,13 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
const int kReceiverOffset = kArgumentsOffset + kPointerSize; const int kReceiverOffset = kArgumentsOffset + kPointerSize;
const int kFunctionOffset = kReceiverOffset + kPointerSize; const int kFunctionOffset = kReceiverOffset + kPointerSize;
const int kVectorOffset =
InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
// Push the vector.
__ lw(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset));
__ Push(a1);
__ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function. __ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function.
__ lw(a1, MemOperand(fp, kArgumentsOffset)); // Get the args array. __ lw(a1, MemOperand(fp, kArgumentsOffset)); // Get the args array.
...@@ -1326,17 +1330,15 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1326,17 +1330,15 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged);
// Push current limit and index. // Push current limit and index.
const int kIndexOffset = const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
const int kLimitOffset =
StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
__ mov(a1, zero_reg); __ mov(a1, zero_reg);
__ lw(a2, MemOperand(fp, kReceiverOffset)); __ lw(a2, MemOperand(fp, kReceiverOffset));
__ Push(v0, a1, a2); // limit, initial index and receiver. __ Push(v0, a1, a2); // limit, initial index and receiver.
// Copy all arguments from the array to the stack. // Copy all arguments from the array to the stack.
Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset, Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
kLimitOffset); kIndexOffset, kLimitOffset);
// Call the callable. // Call the callable.
// TODO(bmeurer): This should be a tail call according to ES6. // TODO(bmeurer): This should be a tail call according to ES6.
...@@ -1360,6 +1362,13 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1360,6 +1362,13 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
const int kArgumentsOffset = kNewTargetOffset + kPointerSize; const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
const int kFunctionOffset = kArgumentsOffset + kPointerSize; const int kFunctionOffset = kArgumentsOffset + kPointerSize;
const int kVectorOffset =
InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
// Push the vector.
__ lw(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset));
__ Push(a1);
// If newTarget is not supplied, set it to constructor // If newTarget is not supplied, set it to constructor
Label validate_arguments; Label validate_arguments;
...@@ -1385,10 +1394,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1385,10 +1394,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged);
// Push current limit and index. // Push current limit and index.
const int kIndexOffset = const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
const int kLimitOffset =
StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
__ push(v0); // limit __ push(v0); // limit
__ mov(a1, zero_reg); // initial index __ mov(a1, zero_reg); // initial index
__ push(a1); __ push(a1);
...@@ -1397,8 +1404,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1397,8 +1404,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
__ push(a0); __ push(a0);
// Copy all arguments from the array to the stack. // Copy all arguments from the array to the stack.
Generate_PushAppliedArguments( Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
masm, kArgumentsOffset, kIndexOffset, kLimitOffset); kIndexOffset, kLimitOffset);
// Use undefined feedback vector // Use undefined feedback vector
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex); __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
......
...@@ -1250,6 +1250,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -1250,6 +1250,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
static void Generate_PushAppliedArguments(MacroAssembler* masm, static void Generate_PushAppliedArguments(MacroAssembler* masm,
const int vectorOffset,
const int argumentsOffset, const int argumentsOffset,
const int indexOffset, const int indexOffset,
const int limitOffset) { const int limitOffset) {
...@@ -1267,13 +1268,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm, ...@@ -1267,13 +1268,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm,
__ ld(receiver, MemOperand(fp, argumentsOffset)); __ ld(receiver, MemOperand(fp, argumentsOffset));
// Use inline caching to speed up access to arguments. // Use inline caching to speed up access to arguments.
Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex();
FeedbackVectorSpec spec(0, 1, kinds); __ li(slot, Operand(Smi::FromInt(slot_index)));
Handle<TypeFeedbackVector> feedback_vector = __ ld(vector, MemOperand(fp, vectorOffset));
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
__ li(slot, Operand(Smi::FromInt(index)));
__ li(vector, feedback_vector);
Handle<Code> ic = Handle<Code> ic =
KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
...@@ -1307,6 +1304,13 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1307,6 +1304,13 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
const int kReceiverOffset = kArgumentsOffset + kPointerSize; const int kReceiverOffset = kArgumentsOffset + kPointerSize;
const int kFunctionOffset = kReceiverOffset + kPointerSize; const int kFunctionOffset = kReceiverOffset + kPointerSize;
const int kVectorOffset =
InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
// Push the vector.
__ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ ld(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset));
__ Push(a1);
__ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function. __ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function.
__ ld(a1, MemOperand(fp, kArgumentsOffset)); // Get the args array. __ ld(a1, MemOperand(fp, kArgumentsOffset)); // Get the args array.
...@@ -1324,17 +1328,15 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1324,17 +1328,15 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged);
// Push current limit and index. // Push current limit and index.
const int kIndexOffset = const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
const int kLimitOffset =
StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
__ mov(a1, zero_reg); __ mov(a1, zero_reg);
__ ld(a2, MemOperand(fp, kReceiverOffset)); __ ld(a2, MemOperand(fp, kReceiverOffset));
__ Push(v0, a1, a2); // limit, initial index and receiver. __ Push(v0, a1, a2); // limit, initial index and receiver.
// Copy all arguments from the array to the stack. // Copy all arguments from the array to the stack.
Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset, Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
kLimitOffset); kIndexOffset, kLimitOffset);
// Call the callable. // Call the callable.
// TODO(bmeurer): This should be a tail call according to ES6. // TODO(bmeurer): This should be a tail call according to ES6.
...@@ -1358,6 +1360,13 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1358,6 +1360,13 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
const int kArgumentsOffset = kNewTargetOffset + kPointerSize; const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
const int kFunctionOffset = kArgumentsOffset + kPointerSize; const int kFunctionOffset = kArgumentsOffset + kPointerSize;
const int kVectorOffset =
InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
// Push the vector.
__ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ ld(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset));
__ Push(a1);
// If newTarget is not supplied, set it to constructor // If newTarget is not supplied, set it to constructor
Label validate_arguments; Label validate_arguments;
...@@ -1383,10 +1392,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1383,10 +1392,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged);
// Push current limit and index. // Push current limit and index.
const int kIndexOffset = const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
const int kLimitOffset =
StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
__ push(v0); // limit __ push(v0); // limit
__ mov(a1, zero_reg); // initial index __ mov(a1, zero_reg); // initial index
__ push(a1); __ push(a1);
...@@ -1395,8 +1402,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1395,8 +1402,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
__ push(a0); __ push(a0);
// Copy all arguments from the array to the stack. // Copy all arguments from the array to the stack.
Generate_PushAppliedArguments( Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
masm, kArgumentsOffset, kIndexOffset, kLimitOffset); kIndexOffset, kLimitOffset);
// Use undefined feedback vector // Use undefined feedback vector
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex); __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
......
...@@ -125,6 +125,26 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate, ...@@ -125,6 +125,26 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate,
} }
// static
int TypeFeedbackVector::PushAppliedArgumentsIndex() {
const int index_count = VectorICComputer::word_count(1);
return kReservedIndexCount + index_count;
}
// static
Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector(
Isolate* isolate) {
Code::Kind kinds[] = {Code::KEYED_LOAD_IC};
FeedbackVectorSpec spec(0, 1, kinds);
Handle<TypeFeedbackVector> feedback_vector =
isolate->factory()->NewTypeFeedbackVector(&spec);
DCHECK(PushAppliedArgumentsIndex() ==
feedback_vector->GetIndex(FeedbackVectorICSlot(0)));
return feedback_vector;
}
// static // static
Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
Isolate* isolate, Handle<TypeFeedbackVector> vector) { Isolate* isolate, Handle<TypeFeedbackVector> vector) {
......
...@@ -181,6 +181,10 @@ class TypeFeedbackVector : public FixedArray { ...@@ -181,6 +181,10 @@ class TypeFeedbackVector : public FixedArray {
return FeedbackVectorICSlot(dummyIndex); return FeedbackVectorICSlot(dummyIndex);
} }
static int PushAppliedArgumentsIndex();
static Handle<TypeFeedbackVector> CreatePushAppliedArgumentsVector(
Isolate* isolate);
private: private:
enum VectorICKind { enum VectorICKind {
KindUnused = 0x0, KindUnused = 0x0,
......
...@@ -1055,6 +1055,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -1055,6 +1055,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
static void Generate_PushAppliedArguments(MacroAssembler* masm, static void Generate_PushAppliedArguments(MacroAssembler* masm,
const int vectorOffset,
const int argumentsOffset, const int argumentsOffset,
const int indexOffset, const int indexOffset,
const int limitOffset) { const int limitOffset) {
...@@ -1071,13 +1072,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm, ...@@ -1071,13 +1072,9 @@ static void Generate_PushAppliedArguments(MacroAssembler* masm,
__ movp(receiver, Operand(rbp, argumentsOffset)); // load arguments __ movp(receiver, Operand(rbp, argumentsOffset)); // load arguments
// Use inline caching to speed up access to arguments. // Use inline caching to speed up access to arguments.
Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex();
FeedbackVectorSpec spec(0, 1, kinds); __ Move(slot, Smi::FromInt(slot_index));
Handle<TypeFeedbackVector> feedback_vector = __ movp(vector, Operand(rbp, vectorOffset));
masm->isolate()->factory()->NewTypeFeedbackVector(&spec);
int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0));
__ Move(slot, Smi::FromInt(index));
__ Move(vector, feedback_vector);
Handle<Code> ic = Handle<Code> ic =
KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
...@@ -1124,6 +1121,13 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1124,6 +1121,13 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
static const int kReceiverOffset = kArgumentsOffset + kPointerSize; static const int kReceiverOffset = kArgumentsOffset + kPointerSize;
static const int kFunctionOffset = kReceiverOffset + kPointerSize; static const int kFunctionOffset = kReceiverOffset + kPointerSize;
static const int kVectorOffset =
InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
// Push the vector.
__ movp(rdi, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ movp(rdi, FieldOperand(rdi, SharedFunctionInfo::kFeedbackVectorOffset));
__ Push(rdi);
__ Push(Operand(rbp, kFunctionOffset)); __ Push(Operand(rbp, kFunctionOffset));
__ Push(Operand(rbp, kArgumentsOffset)); __ Push(Operand(rbp, kArgumentsOffset));
...@@ -1137,16 +1141,15 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { ...@@ -1137,16 +1141,15 @@ static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged);
// Push current index and limit, and receiver. // Push current index and limit, and receiver.
const int kLimitOffset = const int kLimitOffset = kVectorOffset - 1 * kPointerSize;
StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
const int kIndexOffset = kLimitOffset - 1 * kPointerSize; const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
__ Push(rax); // limit __ Push(rax); // limit
__ Push(Immediate(0)); // index __ Push(Immediate(0)); // index
__ Push(Operand(rbp, kReceiverOffset)); // receiver __ Push(Operand(rbp, kReceiverOffset)); // receiver
// Loop over the arguments array, pushing each value to the stack // Loop over the arguments array, pushing each value to the stack
Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset, Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
kLimitOffset); kIndexOffset, kLimitOffset);
// Call the callable. // Call the callable.
// TODO(bmeurer): This should be a tail call according to ES6. // TODO(bmeurer): This should be a tail call according to ES6.
...@@ -1181,6 +1184,14 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1181,6 +1184,14 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; static const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
static const int kFunctionOffset = kArgumentsOffset + kPointerSize; static const int kFunctionOffset = kArgumentsOffset + kPointerSize;
static const int kVectorOffset =
InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
// Push the vector.
__ movp(rdi, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ movp(rdi, FieldOperand(rdi, SharedFunctionInfo::kFeedbackVectorOffset));
__ Push(rdi);
// If newTarget is not supplied, set it to constructor // If newTarget is not supplied, set it to constructor
Label validate_arguments; Label validate_arguments;
__ movp(rax, Operand(rbp, kNewTargetOffset)); __ movp(rax, Operand(rbp, kNewTargetOffset));
...@@ -1200,8 +1211,7 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1200,8 +1211,7 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged);
// Push current index and limit. // Push current index and limit.
const int kLimitOffset = const int kLimitOffset = kVectorOffset - 1 * kPointerSize;
StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
const int kIndexOffset = kLimitOffset - 1 * kPointerSize; const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
__ Push(rax); // limit __ Push(rax); // limit
__ Push(Immediate(0)); // index __ Push(Immediate(0)); // index
...@@ -1209,8 +1219,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) { ...@@ -1209,8 +1219,8 @@ static void Generate_ConstructHelper(MacroAssembler* masm) {
__ Push(Operand(rbp, kFunctionOffset)); __ Push(Operand(rbp, kFunctionOffset));
// Loop over the arguments array, pushing each value to the stack // Loop over the arguments array, pushing each value to the stack
Generate_PushAppliedArguments( Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
masm, kArgumentsOffset, kIndexOffset, kLimitOffset); kIndexOffset, kLimitOffset);
// Use undefined feedback vector // Use undefined feedback vector
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
......
...@@ -3909,8 +3909,14 @@ static void CheckVectorIC(Handle<JSFunction> f, int ic_slot_index, ...@@ -3909,8 +3909,14 @@ static void CheckVectorIC(Handle<JSFunction> f, int ic_slot_index,
Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector> vector =
Handle<TypeFeedbackVector>(f->shared()->feedback_vector()); Handle<TypeFeedbackVector>(f->shared()->feedback_vector());
FeedbackVectorICSlot slot(ic_slot_index); FeedbackVectorICSlot slot(ic_slot_index);
LoadICNexus nexus(vector, slot); if (vector->GetKind(slot) == Code::LOAD_IC) {
CHECK(nexus.StateFromFeedback() == desired_state); LoadICNexus nexus(vector, slot);
CHECK(nexus.StateFromFeedback() == desired_state);
} else {
CHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC);
KeyedLoadICNexus nexus(vector, slot);
CHECK(nexus.StateFromFeedback() == desired_state);
}
} }
...@@ -3923,6 +3929,38 @@ static void CheckVectorICCleared(Handle<JSFunction> f, int ic_slot_index) { ...@@ -3923,6 +3929,38 @@ static void CheckVectorICCleared(Handle<JSFunction> f, int ic_slot_index) {
} }
TEST(ICInBuiltInIsClearedAppropriately) {
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Handle<JSFunction> apply;
{
LocalContext env;
v8::Local<v8::Value> res = CompileRun("Function.apply");
Handle<JSObject> maybe_apply =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
apply = Handle<JSFunction>::cast(maybe_apply);
TypeFeedbackVector* vector = apply->shared()->feedback_vector();
CHECK(vector->ICSlots() == 1);
CheckVectorIC(apply, 0, UNINITIALIZED);
CompileRun(
"function b(a1, a2, a3) { return a1 + a2 + a3; }"
"function fun(bar) { bar.apply({}, [1, 2, 3]); };"
"fun(b); fun(b)");
CheckVectorIC(apply, 0, MONOMORPHIC);
}
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
// The IC in apply has been cleared, ready to learn again.
CheckVectorIC(apply, 0, PREMONOMORPHIC);
}
TEST(IncrementalMarkingPreservesMonomorphicConstructor) { TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
if (i::FLAG_always_opt) return; if (i::FLAG_always_opt) return;
CcTest::InitializeVM(); CcTest::InitializeVM();
...@@ -6524,9 +6562,12 @@ TEST(SharedFunctionInfoIterator) { ...@@ -6524,9 +6562,12 @@ TEST(SharedFunctionInfoIterator) {
// Shared function infos without a script (API functions or C++ builtins) // Shared function infos without a script (API functions or C++ builtins)
// are not returned by the iterator because they are not created from a // are not returned by the iterator because they are not created from a
// script. They are not interesting for type feedback vector anyways. // script. They are not interesting for type feedback vector anyways.
// TODO(mvstanton): There are builtins that use type feedback vectors,
// consider adding these to the iterator.
SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
if (shared->script()->IsUndefined()) { if (shared->script()->IsUndefined()) {
CHECK_EQ(0, shared->feedback_vector()->ICSlots()); CHECK(shared->native() || 0 == shared->feedback_vector()->ICSlots());
} else { } else {
sfi_count++; sfi_count++;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment