Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Unified Diff: src/builtins/ia32/builtins-ia32.cc

Issue 2307903002: [Interpreter] Collect allocation site feedback in call bytecode handler. (Closed)
Patch Set: corrected few comments. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/builtins/ia32/builtins-ia32.cc
diff --git a/src/builtins/ia32/builtins-ia32.cc b/src/builtins/ia32/builtins-ia32.cc
index b1a5cccb2dc1602675c29c03313bdd0a7abf36aa..b099c6ba4980ed08ff15262458bc279a6e37b79a 100644
--- a/src/builtins/ia32/builtins-ia32.cc
+++ b/src/builtins/ia32/builtins-ia32.cc
@@ -761,42 +761,40 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
}
}
-// static
-void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
- MacroAssembler* masm, CallableType construct_type) {
- // ----------- S t a t e -------------
- // -- eax : the number of arguments (not including the receiver)
- // -- edx : the new target
- // -- edi : the constructor
- // -- ebx : allocation site feedback (if available or undefined)
- // -- ecx : the address of the first argument to be pushed. Subsequent
- // arguments should be consecutive above this, in the same order as
- // they are to be pushed onto the stack.
- // -----------------------------------
+namespace {
- // Store edi, edx onto the stack. We need two extra registers
- // so store edi, edx temporarily on stack.
- __ Push(edi);
- __ Push(edx);
+// This function modified start_addr, and only reads the contents of num_args
+// register. reg1 and reg2 are used as temporary registers. Their original
+// values are restored after the use. reg1 and reg2 will be pushed onto the
+// stack, so they should either have an Smi or a tagged pointer.
rmcilroy 2016/09/07 10:57:39 Do reg1/reg2 need to be tagged? They are pushed, b
mythria 2016/09/07 13:11:15 As mentioned offline, I was thinking about interru
+void Generate_InterpreterPushArgsAndReturnAddress(MacroAssembler* masm,
+ Register num_args,
+ Register start_addr,
+ Register reg1, Register reg2,
rmcilroy 2016/09/07 10:57:39 nit - reg1 / reg2 -> scratch1 / scratch2 (also upd
mythria 2016/09/07 13:11:16 Done.
+ bool receiver_in_args) {
+ // Store reg2, reg1 onto the stack. We need to restore the original values
+ // so store reg2, reg1 temporarily on stack.
+ __ Push(reg2);
+ __ Push(reg1);
// We have to pop return address and the two temporary registers before we
// can push arguments onto the stack. we do not have any free registers so
// update the stack and copy them into the correct places on the stack.
// current stack =====> required stack layout
- // | | | edx | (2) <-- esp(1)
- // | | | edi | (3)
+ // | | | reg1 | (2) <-- esp(1)
+ // | | | reg2 | (3)
// | | | return addr | (4)
// | | | arg N | (5)
- // | edx | <-- esp | .... |
- // | edi | | arg 0 |
+ // | reg1 | <-- esp | .... |
+ // | reg2 | | arg 0 |
// | return addr | | receiver slot |
// First increment the stack pointer to the correct location.
// we need additional slots for arguments and the receiver.
// Step 1 - compute the required increment to the stack.
- __ mov(edx, eax);
- __ shl(edx, kPointerSizeLog2);
- __ add(edx, Immediate(kPointerSize));
+ __ mov(reg1, num_args);
+ __ shl(reg1, kPointerSizeLog2);
+ __ add(reg1, Immediate(kPointerSize));
#ifdef _MSC_VER
// TODO(mythria): Move it to macro assembler.
@@ -807,12 +805,12 @@ void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
const int page_size = 4 * 1024;
Label check_offset, update_stack_pointer;
__ bind(&check_offset);
- __ cmp(edx, page_size);
+ __ cmp(reg1, page_size);
__ j(less, &update_stack_pointer);
__ sub(esp, Immediate(page_size));
// Just to touch the page, before we increment further.
__ mov(Operand(esp, 0), Immediate(0));
- __ sub(edx, Immediate(page_size));
+ __ sub(reg1, Immediate(page_size));
__ jmp(&check_offset);
__ bind(&update_stack_pointer);
#endif
@@ -820,44 +818,71 @@ void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
// TODO(mythria): Add a stack check before updating the stack pointer.
// Step 1 - Update the stack pointer.
- __ sub(esp, edx);
+ __ sub(esp, reg1);
- // Step 2 move edx to the correct location. Move edx first otherwise
- // we may overwrite when eax = 0 or 1, basically when the source and
+ // Step 2 move reg1 to the correct location. Move reg1 first otherwise
+ // we may overwrite when num_args = 0 or 1, basically when the source and
// destination overlap. We at least need one extra slot for receiver,
// so no extra checks are required to avoid copy.
- __ mov(edi, Operand(esp, eax, times_pointer_size, 1 * kPointerSize));
- __ mov(Operand(esp, 0), edi);
+ __ mov(reg1, Operand(esp, num_args, times_pointer_size, 1 * kPointerSize));
+ __ mov(Operand(esp, 0), reg1);
- // Step 3 move edi to the correct location
- __ mov(edi, Operand(esp, eax, times_pointer_size, 2 * kPointerSize));
- __ mov(Operand(esp, 1 * kPointerSize), edi);
+ // Step 3 move reg2 to the correct location
+ __ mov(reg1, Operand(esp, num_args, times_pointer_size, 2 * kPointerSize));
+ __ mov(Operand(esp, 1 * kPointerSize), reg1);
// Step 4 move return address to the correct location
- __ mov(edi, Operand(esp, eax, times_pointer_size, 3 * kPointerSize));
- __ mov(Operand(esp, 2 * kPointerSize), edi);
-
- // Slot meant for receiver contains return address. Reset it so that
- // we will not incorrectly interpret return address as an object.
- __ mov(Operand(esp, eax, times_pointer_size, 3 * kPointerSize), Immediate(0));
+ __ mov(reg1, Operand(esp, num_args, times_pointer_size, 3 * kPointerSize));
+ __ mov(Operand(esp, 2 * kPointerSize), reg1);
// Step 5 copy arguments to correct locations.
- __ mov(edx, eax);
+ if (receiver_in_args) {
+ __ mov(reg1, num_args);
+ __ add(reg1, Immediate(1));
+ } else {
+ // Slot meant for receiver contains return address. Reset it so that
+ // we will not incorrectly interpret return address as an object.
+ __ mov(Operand(esp, num_args, times_pointer_size, 3 * kPointerSize),
+ Immediate(0));
+ __ mov(reg1, num_args);
+ }
Label loop_header, loop_check;
__ jmp(&loop_check);
__ bind(&loop_header);
- __ mov(edi, Operand(ecx, 0));
- __ mov(Operand(esp, edx, times_pointer_size, 2 * kPointerSize), edi);
- __ sub(ecx, Immediate(kPointerSize));
- __ sub(edx, Immediate(1));
+ __ mov(reg2, Operand(start_addr, 0));
+ __ mov(Operand(esp, reg1, times_pointer_size, 2 * kPointerSize), reg2);
+ __ sub(start_addr, Immediate(kPointerSize));
+ __ sub(reg1, Immediate(1));
__ bind(&loop_check);
- __ cmp(edx, Immediate(0));
+ __ cmp(reg1, Immediate(0));
__ j(greater, &loop_header, Label::kNear);
- // Restore edi and edx.
- __ Pop(edx);
- __ Pop(edi);
+ // Restore reg1 and reg2.
+ __ Pop(reg1);
+ __ Pop(reg2);
+}
+
+} // end anonymous namespace
+
+// static
+void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
+ MacroAssembler* masm, CallableType construct_type) {
+ // ----------- S t a t e -------------
+ // -- eax : the number of arguments (not including the receiver)
+ // -- edx : the new target
+ // -- edi : the constructor
+ // -- ebx : allocation site feedback (if available or undefined)
+ // -- ecx : the address of the first argument to be pushed. Subsequent
+ // arguments should be consecutive above this, in the same order as
+ // they are to be pushed onto the stack.
+ // -----------------------------------
+
+ // Push arguments and move return address to the top of stack.
+ // eax is readonly. ecx will be modified. edx and edi will be modified but
rmcilroy 2016/09/07 10:57:39 Capitalize start of sentences (e.g., do "The eax r
mythria 2016/09/07 13:11:15 Done.
+ // restored to their original values. edx and edi will be pushed onto the
+ // stack, so ensure they have an Smi or tagged pointer.
+ Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, false);
__ AssertUndefinedOrAllocationSite(ebx);
if (construct_type == CallableType::kJSFunction) {
@@ -877,6 +902,31 @@ void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
}
}
+// static
+void Builtins::Generate_InterpreterPushArgsAndConstructArray(
+ MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- eax : the number of arguments (not including the receiver)
+ // -- edx : the target to call checked to be Array function.
+ // -- ebx : the allocation site feedback
+ // -- ecx : the address of the first argument to be pushed. Subsequent
+ // arguments should be consecutive above this, in the same order as
+ // they are to be pushed onto the stack.
+ // -----------------------------------
+
+ // Push arguments and move return address to the top of stack.
+ // eax is readonly. ecx will be modified. edx and ebx will be modified but
+ // restored to their original values. edx and ebx will be pushed onto the
+ // stack, so ensure they have an Smi or tagged pointer.
+ Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, ebx, true);
+
+ // Array constructor expects constructor in edi. It is same as edx here.
+ __ Move(edi, edx);
+
+ ArrayConstructorStub stub(masm->isolate());
+ __ TailCallStub(&stub);
+}
+
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
// Set the return address to the correct point in the interpreter entry
// trampoline.

Powered by Google App Engine
This is Rietveld 408576698