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

Side by Side Diff: src/full-codegen/mips64/full-codegen-mips64.cc

Issue 1492793002: [fullcode] Switch passing of new.target to register. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Ported. Created 5 years 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 unified diff | Download patch
« no previous file with comments | « src/full-codegen/mips/full-codegen-mips.cc ('k') | src/full-codegen/x64/full-codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
6 6
7 // Note on Mips implementation: 7 // Note on Mips implementation:
8 // 8 //
9 // The result_register() for mips is the 'v0' register, which is defined 9 // The result_register() for mips is the 'v0' register, which is defined
10 // by the ABI to contain function return values. However, the first 10 // by the ABI to contain function return values. However, the first
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 }; 94 };
95 95
96 96
97 // Generate code for a JS function. On entry to the function the receiver 97 // Generate code for a JS function. On entry to the function the receiver
98 // and arguments have been pushed on the stack left to right. The actual 98 // and arguments have been pushed on the stack left to right. The actual
99 // argument count matches the formal parameter count expected by the 99 // argument count matches the formal parameter count expected by the
100 // function. 100 // function.
101 // 101 //
102 // The live registers are: 102 // The live registers are:
103 // o a1: the JS function object being called (i.e. ourselves) 103 // o a1: the JS function object being called (i.e. ourselves)
104 // o a3: the new target value
104 // o cp: our context 105 // o cp: our context
105 // o fp: our caller's frame pointer 106 // o fp: our caller's frame pointer
106 // o sp: stack pointer 107 // o sp: stack pointer
107 // o ra: return address 108 // o ra: return address
108 // 109 //
109 // The function builds a JS frame. Please see JavaScriptFrameConstants in 110 // The function builds a JS frame. Please see JavaScriptFrameConstants in
110 // frames-mips.h for its layout. 111 // frames-mips.h for its layout.
111 void FullCodeGenerator::Generate() { 112 void FullCodeGenerator::Generate() {
112 CompilationInfo* info = info_; 113 CompilationInfo* info = info_;
113 profiling_counter_ = isolate()->factory()->NewCell( 114 profiling_counter_ = isolate()->factory()->NewCell(
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 if (info->scope()->num_heap_slots() > 0) { 185 if (info->scope()->num_heap_slots() > 0) {
185 Comment cmnt(masm_, "[ Allocate context"); 186 Comment cmnt(masm_, "[ Allocate context");
186 // Argument to NewContext is the function, which is still in a1. 187 // Argument to NewContext is the function, which is still in a1.
187 bool need_write_barrier = true; 188 bool need_write_barrier = true;
188 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 189 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
189 if (info->scope()->is_script_scope()) { 190 if (info->scope()->is_script_scope()) {
190 __ push(a1); 191 __ push(a1);
191 __ Push(info->scope()->GetScopeInfo(info->isolate())); 192 __ Push(info->scope()->GetScopeInfo(info->isolate()));
192 __ CallRuntime(Runtime::kNewScriptContext, 2); 193 __ CallRuntime(Runtime::kNewScriptContext, 2);
193 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 194 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG);
194 } else if (slots <= FastNewContextStub::kMaximumSlots) { 195 // The new target value is not used, clobbering is safe.
195 FastNewContextStub stub(isolate(), slots); 196 DCHECK_NULL(info->scope()->new_target_var());
196 __ CallStub(&stub);
197 // Result of FastNewContextStub is always in new space.
198 need_write_barrier = false;
199 } else { 197 } else {
200 __ push(a1); 198 if (info->scope()->new_target_var() != nullptr) {
201 __ CallRuntime(Runtime::kNewFunctionContext, 1); 199 __ push(a3); // Preserve new target.
200 }
201 if (slots <= FastNewContextStub::kMaximumSlots) {
202 FastNewContextStub stub(isolate(), slots);
203 __ CallStub(&stub);
204 // Result of FastNewContextStub is always in new space.
205 need_write_barrier = false;
206 } else {
207 __ push(a1);
208 __ CallRuntime(Runtime::kNewFunctionContext, 1);
209 }
210 if (info->scope()->new_target_var() != nullptr) {
211 __ pop(a3); // Restore new target.
212 }
202 } 213 }
203 function_in_register_a1 = false; 214 function_in_register_a1 = false;
204 // Context is returned in v0. It replaces the context passed to us. 215 // Context is returned in v0. It replaces the context passed to us.
205 // It's saved in the stack and kept live in cp. 216 // It's saved in the stack and kept live in cp.
206 __ mov(cp, v0); 217 __ mov(cp, v0);
207 __ sd(v0, MemOperand(fp, StandardFrameConstants::kContextOffset)); 218 __ sd(v0, MemOperand(fp, StandardFrameConstants::kContextOffset));
208 // Copy any necessary parameters into the context. 219 // Copy any necessary parameters into the context.
209 int num_parameters = info->scope()->num_parameters(); 220 int num_parameters = info->scope()->num_parameters();
210 int first_parameter = info->scope()->has_this_declaration() ? -1 : 0; 221 int first_parameter = info->scope()->has_this_declaration() ? -1 : 0;
211 for (int i = first_parameter; i < num_parameters; i++) { 222 for (int i = first_parameter; i < num_parameters; i++) {
212 Variable* var = (i == -1) ? scope()->receiver() : scope()->parameter(i); 223 Variable* var = (i == -1) ? scope()->receiver() : scope()->parameter(i);
213 if (var->IsContextSlot()) { 224 if (var->IsContextSlot()) {
214 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 225 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
215 (num_parameters - 1 - i) * kPointerSize; 226 (num_parameters - 1 - i) * kPointerSize;
216 // Load parameter from stack. 227 // Load parameter from stack.
217 __ ld(a0, MemOperand(fp, parameter_offset)); 228 __ ld(a0, MemOperand(fp, parameter_offset));
218 // Store it in the context. 229 // Store it in the context.
219 MemOperand target = ContextMemOperand(cp, var->index()); 230 MemOperand target = ContextMemOperand(cp, var->index());
220 __ sd(a0, target); 231 __ sd(a0, target);
221 232
222 // Update the write barrier. 233 // Update the write barrier.
223 if (need_write_barrier) { 234 if (need_write_barrier) {
224 __ RecordWriteContextSlot( 235 __ RecordWriteContextSlot(cp, target.offset(), a0, a2,
225 cp, target.offset(), a0, a3, kRAHasBeenSaved, kDontSaveFPRegs); 236 kRAHasBeenSaved, kDontSaveFPRegs);
226 } else if (FLAG_debug_code) { 237 } else if (FLAG_debug_code) {
227 Label done; 238 Label done;
228 __ JumpIfInNewSpace(cp, a0, &done); 239 __ JumpIfInNewSpace(cp, a0, &done);
229 __ Abort(kExpectedNewSpaceObject); 240 __ Abort(kExpectedNewSpaceObject);
230 __ bind(&done); 241 __ bind(&done);
231 } 242 }
232 } 243 }
233 } 244 }
234 } 245 }
246
247 // Register holding this function and new target are both trashed in case we
248 // bailout here. But since that can happen only when new target is not used
249 // and we allocate a context, the value of |function_in_register| is correct.
235 PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); 250 PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS);
236 251
237 // Function register is trashed in case we bailout here. But since that
238 // could happen only when we allocate a context the value of
239 // |function_in_register_a1| is correct.
240
241 // Possibly set up a local binding to the this function which is used in 252 // Possibly set up a local binding to the this function which is used in
242 // derived constructors with super calls. 253 // derived constructors with super calls.
243 Variable* this_function_var = scope()->this_function_var(); 254 Variable* this_function_var = scope()->this_function_var();
244 if (this_function_var != nullptr) { 255 if (this_function_var != nullptr) {
245 Comment cmnt(masm_, "[ This function"); 256 Comment cmnt(masm_, "[ This function");
246 if (!function_in_register_a1) { 257 if (!function_in_register_a1) {
247 __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 258 __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
248 // The write barrier clobbers register again, keep it marked as such. 259 // The write barrier clobbers register again, keep it marked as such.
249 } 260 }
250 SetVar(this_function_var, a1, a2, a3); 261 SetVar(this_function_var, a1, a0, a2);
251 } 262 }
252 263
253 Variable* new_target_var = scope()->new_target_var(); 264 Variable* new_target_var = scope()->new_target_var();
254 if (new_target_var != nullptr) { 265 if (new_target_var != nullptr) {
255 Comment cmnt(masm_, "[ new.target"); 266 Comment cmnt(masm_, "[ new.target");
256 // Get the frame pointer for the calling frame. 267 SetVar(new_target_var, a3, a0, a2);
257 __ ld(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
258
259 // Skip the arguments adaptor frame if it exists.
260 Label check_frame_marker;
261 __ ld(a1, MemOperand(a2, StandardFrameConstants::kContextOffset));
262 __ Branch(&check_frame_marker, ne, a1,
263 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
264 __ ld(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset));
265
266 // Check the marker in the calling frame.
267 __ bind(&check_frame_marker);
268 __ ld(a1, MemOperand(a2, StandardFrameConstants::kMarkerOffset));
269 function_in_register_a1 = false;
270
271 Label non_construct_frame, done;
272 __ Branch(&non_construct_frame, ne, a1,
273 Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
274
275 __ ld(v0, MemOperand(a2, ConstructFrameConstants::kNewTargetOffset));
276 __ Branch(&done);
277
278 __ bind(&non_construct_frame);
279 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
280 __ bind(&done);
281
282 SetVar(new_target_var, v0, a2, a3);
283 } 268 }
284 269
285 Variable* arguments = scope()->arguments(); 270 Variable* arguments = scope()->arguments();
286 if (arguments != NULL) { 271 if (arguments != NULL) {
287 // Function uses arguments object. 272 // Function uses arguments object.
288 Comment cmnt(masm_, "[ Allocate arguments object"); 273 Comment cmnt(masm_, "[ Allocate arguments object");
289 DCHECK(a1.is(ArgumentsAccessNewDescriptor::function())); 274 DCHECK(a1.is(ArgumentsAccessNewDescriptor::function()));
290 if (!function_in_register_a1) { 275 if (!function_in_register_a1) {
291 // Load this again, if it's used by the local context below. 276 // Load this again, if it's used by the local context below.
292 __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 277 __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
(...skipping 4653 matching lines...) Expand 10 before | Expand all | Expand 10 after
4946 reinterpret_cast<uint64_t>( 4931 reinterpret_cast<uint64_t>(
4947 isolate->builtins()->OsrAfterStackCheck()->entry())); 4932 isolate->builtins()->OsrAfterStackCheck()->entry()));
4948 return OSR_AFTER_STACK_CHECK; 4933 return OSR_AFTER_STACK_CHECK;
4949 } 4934 }
4950 4935
4951 4936
4952 } // namespace internal 4937 } // namespace internal
4953 } // namespace v8 4938 } // namespace v8
4954 4939
4955 #endif // V8_TARGET_ARCH_MIPS64 4940 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/full-codegen/mips/full-codegen-mips.cc ('k') | src/full-codegen/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698