Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 namespace v8 { | 32 namespace v8 { |
| 33 namespace internal { | 33 namespace internal { |
| 34 | 34 |
| 35 #define __ ACCESS_MASM(masm) | 35 #define __ ACCESS_MASM(masm) |
| 36 | 36 |
| 37 void Builtins::Generate_Adaptor(MacroAssembler* masm, | 37 void Builtins::Generate_Adaptor(MacroAssembler* masm, |
| 38 Builtins::CFunctionId id) { | 38 Builtins::CFunctionId id) { |
| 39 masm->int3(); // UNIMPLEMENTED. | 39 masm->int3(); // UNIMPLEMENTED. |
| 40 } | 40 } |
| 41 | 41 |
| 42 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | |
| 43 __ push(rbp); | |
| 44 __ movq(rbp, rsp); | |
| 45 | |
| 46 // Store the arguments adaptor context sentinel. | |
| 47 __ push(Immediate(ArgumentsAdaptorFrame::SENTINEL)); | |
| 48 | |
| 49 // Push the function on the stack. | |
| 50 __ push(rdi); | |
| 51 | |
| 52 // Preserve the number of arguments on the stack. Must preserve both | |
| 53 // eax and ebx because these registers are used when copying the | |
| 54 // arguments and the receiver. | |
| 55 ASSERT(kSmiTagSize == 1); | |
| 56 __ lea(rcx, Operand(rax, rax, kTimes1, kSmiTag)); | |
| 57 __ push(rcx); | |
| 58 } | |
| 59 | |
| 60 | |
| 61 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | |
| 62 // Retrieve the number of arguments from the stack. Number is a Smi. | |
| 63 __ movq(rbx, Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
| 64 | |
| 65 // Leave the frame. | |
| 66 __ movq(rsp, rbp); | |
| 67 __ pop(rbp); | |
| 68 | |
| 69 // Remove caller arguments from the stack. | |
| 70 // rbx holds a Smi. | |
|
William Hesse
2009/06/11 09:32:29
holds a Smi. Therefore, we convert to a dword off
| |
| 71 ASSERT_EQ(kSmiTagSize, 1 && kSmiTag == 0); | |
| 72 ASSERT_EQ(kPointerSize, (1 << kSmiTagSize) * 4); | |
| 73 __ pop(rcx); | |
| 74 __ lea(rsp, Operand(rsp, rbx, kTimes4, 1 * kPointerSize)); // 1 ~ receiver | |
| 75 __ push(rcx); | |
| 76 } | |
| 77 | |
| 78 | |
| 42 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 79 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
| 43 masm->int3(); // UNIMPLEMENTED. | 80 // ----------- S t a t e ------------- |
| 81 // -- rax : actual number of arguments | |
| 82 // -- rbx : expected number of arguments | |
| 83 // -- rdx : code entry to call | |
| 84 // ----------------------------------- | |
| 85 | |
| 86 Label invoke, dont_adapt_arguments; | |
| 87 __ IncrementCounter(&Counters::arguments_adaptors, 1); | |
| 88 | |
| 89 Label enough, too_few; | |
| 90 __ cmp(rax, rbx); | |
| 91 __ j(less, &too_few); | |
| 92 __ cmp(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); | |
| 93 __ j(equal, &dont_adapt_arguments); | |
| 94 | |
| 95 { // Enough parameters: Actual >= expected. | |
| 96 __ bind(&enough); | |
| 97 EnterArgumentsAdaptorFrame(masm); | |
| 98 | |
| 99 // Copy receiver and all expected arguments. | |
| 100 const int offset = StandardFrameConstants::kCallerSPOffset; | |
| 101 __ lea(rax, Operand(rbp, rax, kTimesPointerSize, offset)); | |
| 102 __ movq(rcx, Immediate(-1)); // account for receiver | |
| 103 | |
| 104 Label copy; | |
| 105 __ bind(©); | |
| 106 __ inc(rcx); | |
| 107 __ push(Operand(rax, 0)); | |
| 108 __ sub(rax, Immediate(kPointerSize)); | |
| 109 __ cmp(rcx, rbx); | |
| 110 __ j(less, ©); | |
| 111 __ jmp(&invoke); | |
| 112 } | |
| 113 | |
| 114 { // Too few parameters: Actual < expected. | |
| 115 __ bind(&too_few); | |
| 116 EnterArgumentsAdaptorFrame(masm); | |
| 117 | |
| 118 // Copy receiver and all actual arguments. | |
| 119 const int offset = StandardFrameConstants::kCallerSPOffset; | |
| 120 __ lea(rdi, Operand(rbp, rax, kTimesPointerSize, offset)); | |
| 121 __ movq(rcx, Immediate(-1)); // account for receiver | |
| 122 | |
| 123 Label copy; | |
| 124 __ bind(©); | |
| 125 __ inc(rcx); | |
| 126 __ push(Operand(rdi, 0)); | |
| 127 __ sub(rdi, Immediate(kPointerSize)); | |
| 128 __ cmp(rcx, rax); | |
| 129 __ j(less, ©); | |
| 130 | |
| 131 // Fill remaining expected arguments with undefined values. | |
| 132 Label fill; | |
| 133 __ movq(kScratchRegister, | |
| 134 Factory::undefined_value(), | |
| 135 RelocInfo::EMBEDDED_OBJECT); | |
| 136 __ bind(&fill); | |
| 137 __ inc(rcx); | |
| 138 __ push(kScratchRegister); | |
| 139 __ cmp(rcx, rbx); | |
| 140 __ j(less, &fill); | |
| 141 | |
| 142 // Restore function pointer. | |
| 143 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | |
| 144 } | |
| 145 | |
| 146 // Call the entry point. | |
| 147 __ bind(&invoke); | |
| 148 __ call(rdx); | |
| 149 | |
| 150 // Leave frame and return. | |
| 151 LeaveArgumentsAdaptorFrame(masm); | |
| 152 __ ret(0); | |
| 153 | |
| 154 // ------------------------------------------- | |
| 155 // Dont adapt arguments. | |
| 156 // ------------------------------------------- | |
| 157 __ bind(&dont_adapt_arguments); | |
| 158 __ jmp(rdx); | |
| 44 } | 159 } |
| 45 | 160 |
| 161 | |
| 46 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 162 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
| 47 masm->int3(); // UNIMPLEMENTED. | 163 masm->int3(); // UNIMPLEMENTED. |
| 48 } | 164 } |
| 49 | 165 |
| 50 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { | 166 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
| 51 masm->int3(); // UNIMPLEMENTED. | 167 masm->int3(); // UNIMPLEMENTED. |
| 52 } | 168 } |
| 53 | 169 |
| 54 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { | 170 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { |
| 55 masm->int3(); // UNIMPLEMENTED. | 171 masm->int3(); // UNIMPLEMENTED. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 75 // rdx : function | 191 // rdx : function |
| 76 // r8 : receiver | 192 // r8 : receiver |
| 77 // r9 : argc | 193 // r9 : argc |
| 78 // [rsp+0x20] : argv | 194 // [rsp+0x20] : argv |
| 79 | 195 |
| 80 // Clear the context before we push it when entering the JS frame. | 196 // Clear the context before we push it when entering the JS frame. |
| 81 __ xor_(rsi, rsi); | 197 __ xor_(rsi, rsi); |
| 82 // Enter an internal frame. | 198 // Enter an internal frame. |
| 83 __ EnterInternalFrame(); | 199 __ EnterInternalFrame(); |
| 84 | 200 |
| 85 | |
| 86 // Load the function context into rsi. | 201 // Load the function context into rsi. |
| 87 __ movq(rsi, FieldOperand(rdx, JSFunction::kContextOffset)); | 202 __ movq(rsi, FieldOperand(rdx, JSFunction::kContextOffset)); |
| 88 | 203 |
| 89 // Push the function and the receiver onto the stack. | 204 // Push the function and the receiver onto the stack. |
| 90 __ push(rdx); | 205 __ push(rdx); |
| 91 __ push(r8); | 206 __ push(r8); |
| 92 | 207 |
| 93 // Load the number of arguments and setup pointer to the arguments. | 208 // Load the number of arguments and setup pointer to the arguments. |
| 94 __ movq(rax, r9); | 209 __ movq(rax, r9); |
| 95 // Load the previous frame pointer to access C argument on stack | 210 // Load the previous frame pointer to access C argument on stack |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 | 263 |
| 149 // Invoke the code. | 264 // Invoke the code. |
| 150 if (is_construct) { | 265 if (is_construct) { |
| 151 // Expects rdi to hold function pointer. | 266 // Expects rdi to hold function pointer. |
| 152 __ movq(kScratchRegister, | 267 __ movq(kScratchRegister, |
| 153 Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)), | 268 Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)), |
| 154 RelocInfo::CODE_TARGET); | 269 RelocInfo::CODE_TARGET); |
| 155 __ call(kScratchRegister); | 270 __ call(kScratchRegister); |
| 156 } else { | 271 } else { |
| 157 ParameterCount actual(rax); | 272 ParameterCount actual(rax); |
| 273 // Function must be in rdi. | |
| 158 __ InvokeFunction(rdi, actual, CALL_FUNCTION); | 274 __ InvokeFunction(rdi, actual, CALL_FUNCTION); |
| 159 } | 275 } |
| 160 | 276 |
| 161 // Exit the JS frame. Notice that this also removes the empty | 277 // Exit the JS frame. Notice that this also removes the empty |
| 162 // context and the function left on the stack by the code | 278 // context and the function left on the stack by the code |
| 163 // invocation. | 279 // invocation. |
| 164 __ LeaveInternalFrame(); | 280 __ LeaveInternalFrame(); |
| 165 // TODO(X64): Is argument correct? Is there a receiver to remove? | 281 // TODO(X64): Is argument correct? Is there a receiver to remove? |
| 166 __ ret(1 * kPointerSize); // remove receiver | 282 __ ret(1 * kPointerSize); // remove receiver |
| 167 } | 283 } |
| 168 | 284 |
| 169 | 285 |
| 170 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 286 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
| 171 Generate_JSEntryTrampolineHelper(masm, false); | 287 Generate_JSEntryTrampolineHelper(masm, false); |
| 172 } | 288 } |
| 173 | 289 |
| 174 | 290 |
| 175 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 291 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
| 176 Generate_JSEntryTrampolineHelper(masm, true); | 292 Generate_JSEntryTrampolineHelper(masm, true); |
| 177 } | 293 } |
| 178 | 294 |
| 179 } } // namespace v8::internal | 295 } } // namespace v8::internal |
| 180 | 296 |
| 181 | 297 |
| OLD | NEW |