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

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

Issue 1494003004: PPC: [fullcode] Switch passing of new.target to register. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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_PPC 5 #if V8_TARGET_ARCH_PPC
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 }; 82 };
83 83
84 84
85 // Generate code for a JS function. On entry to the function the receiver 85 // Generate code for a JS function. On entry to the function the receiver
86 // and arguments have been pushed on the stack left to right. The actual 86 // and arguments have been pushed on the stack left to right. The actual
87 // argument count matches the formal parameter count expected by the 87 // argument count matches the formal parameter count expected by the
88 // function. 88 // function.
89 // 89 //
90 // The live registers are: 90 // The live registers are:
91 // o r4: the JS function object being called (i.e., ourselves) 91 // o r4: the JS function object being called (i.e., ourselves)
92 // o r6: the new target value
92 // o cp: our context 93 // o cp: our context
93 // o fp: our caller's frame pointer (aka r31) 94 // o fp: our caller's frame pointer (aka r31)
94 // o sp: stack pointer 95 // o sp: stack pointer
95 // o lr: return address 96 // o lr: return address
96 // o ip: our own function entry (required by the prologue) 97 // o ip: our own function entry (required by the prologue)
97 // 98 //
98 // The function builds a JS frame. Please see JavaScriptFrameConstants in 99 // The function builds a JS frame. Please see JavaScriptFrameConstants in
99 // frames-ppc.h for its layout. 100 // frames-ppc.h for its layout.
100 void FullCodeGenerator::Generate() { 101 void FullCodeGenerator::Generate() {
101 CompilationInfo* info = info_; 102 CompilationInfo* info = info_;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 if (info->scope()->num_heap_slots() > 0) { 181 if (info->scope()->num_heap_slots() > 0) {
181 // Argument to NewContext is the function, which is still in r4. 182 // Argument to NewContext is the function, which is still in r4.
182 Comment cmnt(masm_, "[ Allocate context"); 183 Comment cmnt(masm_, "[ Allocate context");
183 bool need_write_barrier = true; 184 bool need_write_barrier = true;
184 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 185 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
185 if (info->scope()->is_script_scope()) { 186 if (info->scope()->is_script_scope()) {
186 __ push(r4); 187 __ push(r4);
187 __ Push(info->scope()->GetScopeInfo(info->isolate())); 188 __ Push(info->scope()->GetScopeInfo(info->isolate()));
188 __ CallRuntime(Runtime::kNewScriptContext, 2); 189 __ CallRuntime(Runtime::kNewScriptContext, 2);
189 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 190 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG);
190 } else if (slots <= FastNewContextStub::kMaximumSlots) { 191 // The new target value is not used, clobbering is safe.
191 FastNewContextStub stub(isolate(), slots); 192 DCHECK_NULL(info->scope()->new_target_var());
192 __ CallStub(&stub);
193 // Result of FastNewContextStub is always in new space.
194 need_write_barrier = false;
195 } else { 193 } else {
196 __ push(r4); 194 if (info->scope()->new_target_var() != nullptr) {
197 __ CallRuntime(Runtime::kNewFunctionContext, 1); 195 __ push(r6); // Preserve new target.
196 }
197 if (slots <= FastNewContextStub::kMaximumSlots) {
198 FastNewContextStub stub(isolate(), slots);
199 __ CallStub(&stub);
200 // Result of FastNewContextStub is always in new space.
201 need_write_barrier = false;
202 } else {
203 __ push(r4);
204 __ CallRuntime(Runtime::kNewFunctionContext, 1);
205 }
206 if (info->scope()->new_target_var() != nullptr) {
207 __ pop(r6); // Preserve new target.
208 }
198 } 209 }
199 function_in_register_r4 = false; 210 function_in_register_r4 = false;
200 // Context is returned in r3. It replaces the context passed to us. 211 // Context is returned in r3. It replaces the context passed to us.
201 // It's saved in the stack and kept live in cp. 212 // It's saved in the stack and kept live in cp.
202 __ mr(cp, r3); 213 __ mr(cp, r3);
203 __ StoreP(r3, MemOperand(fp, StandardFrameConstants::kContextOffset)); 214 __ StoreP(r3, MemOperand(fp, StandardFrameConstants::kContextOffset));
204 // Copy any necessary parameters into the context. 215 // Copy any necessary parameters into the context.
205 int num_parameters = info->scope()->num_parameters(); 216 int num_parameters = info->scope()->num_parameters();
206 int first_parameter = info->scope()->has_this_declaration() ? -1 : 0; 217 int first_parameter = info->scope()->has_this_declaration() ? -1 : 0;
207 for (int i = first_parameter; i < num_parameters; i++) { 218 for (int i = first_parameter; i < num_parameters; i++) {
208 Variable* var = (i == -1) ? scope()->receiver() : scope()->parameter(i); 219 Variable* var = (i == -1) ? scope()->receiver() : scope()->parameter(i);
209 if (var->IsContextSlot()) { 220 if (var->IsContextSlot()) {
210 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 221 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
211 (num_parameters - 1 - i) * kPointerSize; 222 (num_parameters - 1 - i) * kPointerSize;
212 // Load parameter from stack. 223 // Load parameter from stack.
213 __ LoadP(r3, MemOperand(fp, parameter_offset), r0); 224 __ LoadP(r3, MemOperand(fp, parameter_offset), r0);
214 // Store it in the context. 225 // Store it in the context.
215 MemOperand target = ContextMemOperand(cp, var->index()); 226 MemOperand target = ContextMemOperand(cp, var->index());
216 __ StoreP(r3, target, r0); 227 __ StoreP(r3, target, r0);
217 228
218 // Update the write barrier. 229 // Update the write barrier.
219 if (need_write_barrier) { 230 if (need_write_barrier) {
220 __ RecordWriteContextSlot(cp, target.offset(), r3, r6, 231 __ RecordWriteContextSlot(cp, target.offset(), r3, r5,
221 kLRHasBeenSaved, kDontSaveFPRegs); 232 kLRHasBeenSaved, kDontSaveFPRegs);
222 } else if (FLAG_debug_code) { 233 } else if (FLAG_debug_code) {
223 Label done; 234 Label done;
224 __ JumpIfInNewSpace(cp, r3, &done); 235 __ JumpIfInNewSpace(cp, r3, &done);
225 __ Abort(kExpectedNewSpaceObject); 236 __ Abort(kExpectedNewSpaceObject);
226 __ bind(&done); 237 __ bind(&done);
227 } 238 }
228 } 239 }
229 } 240 }
230 } 241 }
242
243 // Register holding this function and new target are both trashed in case we
244 // bailout here. But since that can happen only when new target is not used
245 // and we allocate a context, the value of |function_in_register| is correct.
231 PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); 246 PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS);
232 247
233 // Function register is trashed in case we bailout here. But since that
234 // could happen only when we allocate a context the value of
235 // |function_in_register_r4| is correct.
236
237 // Possibly set up a local binding to the this function which is used in 248 // Possibly set up a local binding to the this function which is used in
238 // derived constructors with super calls. 249 // derived constructors with super calls.
239 Variable* this_function_var = scope()->this_function_var(); 250 Variable* this_function_var = scope()->this_function_var();
240 if (this_function_var != nullptr) { 251 if (this_function_var != nullptr) {
241 Comment cmnt(masm_, "[ This function"); 252 Comment cmnt(masm_, "[ This function");
242 if (!function_in_register_r4) { 253 if (!function_in_register_r4) {
243 __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 254 __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
244 // The write barrier clobbers register again, keep it marked as such. 255 // The write barrier clobbers register again, keep it marked as such.
245 } 256 }
246 SetVar(this_function_var, r4, r3, r5); 257 SetVar(this_function_var, r4, r3, r5);
247 } 258 }
248 259
260 // Possibly set up a local binding to the new target value.
249 Variable* new_target_var = scope()->new_target_var(); 261 Variable* new_target_var = scope()->new_target_var();
250 if (new_target_var != nullptr) { 262 if (new_target_var != nullptr) {
251 Comment cmnt(masm_, "[ new.target"); 263 Comment cmnt(masm_, "[ new.target");
252 264 SetVar(new_target_var, r6, r3, r5);
253 // Get the frame pointer for the calling frame.
254 __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
255
256 // Skip the arguments adaptor frame if it exists.
257 __ LoadP(r4, MemOperand(r5, StandardFrameConstants::kContextOffset));
258 __ CmpSmiLiteral(r4, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
259 Label skip;
260 __ bne(&skip);
261 __ LoadP(r5, MemOperand(r5, StandardFrameConstants::kCallerFPOffset));
262 __ bind(&skip);
263
264 // Check the marker in the calling frame.
265 __ LoadP(r4, MemOperand(r5, StandardFrameConstants::kMarkerOffset));
266 __ CmpSmiLiteral(r4, Smi::FromInt(StackFrame::CONSTRUCT), r0);
267 Label non_construct_frame, done;
268 function_in_register_r4 = false;
269
270 __ bne(&non_construct_frame);
271 __ LoadP(r3, MemOperand(r5, ConstructFrameConstants::kNewTargetOffset));
272 __ b(&done);
273
274 __ bind(&non_construct_frame);
275 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
276 __ bind(&done);
277
278 SetVar(new_target_var, r3, r5, r6);
279 } 265 }
280 266
281 Variable* arguments = scope()->arguments(); 267 Variable* arguments = scope()->arguments();
282 if (arguments != NULL) { 268 if (arguments != NULL) {
283 // Function uses arguments object. 269 // Function uses arguments object.
284 Comment cmnt(masm_, "[ Allocate arguments object"); 270 Comment cmnt(masm_, "[ Allocate arguments object");
285 DCHECK(r4.is(ArgumentsAccessNewDescriptor::function())); 271 DCHECK(r4.is(ArgumentsAccessNewDescriptor::function()));
286 if (!function_in_register_r4) { 272 if (!function_in_register_r4) {
287 // Load this again, if it's used by the local context below. 273 // Load this again, if it's used by the local context below.
288 __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 274 __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
(...skipping 4630 matching lines...) Expand 10 before | Expand all | Expand 10 after
4919 return ON_STACK_REPLACEMENT; 4905 return ON_STACK_REPLACEMENT;
4920 } 4906 }
4921 4907
4922 DCHECK(interrupt_address == 4908 DCHECK(interrupt_address ==
4923 isolate->builtins()->OsrAfterStackCheck()->entry()); 4909 isolate->builtins()->OsrAfterStackCheck()->entry());
4924 return OSR_AFTER_STACK_CHECK; 4910 return OSR_AFTER_STACK_CHECK;
4925 } 4911 }
4926 } // namespace internal 4912 } // namespace internal
4927 } // namespace v8 4913 } // namespace v8
4928 #endif // V8_TARGET_ARCH_PPC 4914 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698