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

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

Issue 207543003: Do stack checks while pushing locals (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 6 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/arm64/full-codegen-arm64.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 // 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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 104
105 private: 105 private:
106 MacroAssembler* masm_; 106 MacroAssembler* masm_;
107 Label patch_site_; 107 Label patch_site_;
108 #ifdef DEBUG 108 #ifdef DEBUG
109 bool info_emitted_; 109 bool info_emitted_;
110 #endif 110 #endif
111 }; 111 };
112 112
113 113
114 static void EmitStackCheck(MacroAssembler* masm_,
115 Register stack_limit_scratch,
116 int pointers = 0,
117 Register scratch = sp) {
118 Isolate* isolate = masm_->isolate();
119 Label ok;
120 ASSERT(scratch.is(sp) == (pointers == 0));
121 if (pointers != 0) {
122 __ sub(scratch, sp, Operand(pointers * kPointerSize));
123 }
124 __ LoadRoot(stack_limit_scratch, Heap::kStackLimitRootIndex);
125 __ cmp(scratch, Operand(stack_limit_scratch));
126 __ b(hs, &ok);
127 PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize);
128 __ Call(isolate->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
129 __ bind(&ok);
130 }
131
132
114 // Generate code for a JS function. On entry to the function the receiver 133 // Generate code for a JS function. On entry to the function the receiver
115 // and arguments have been pushed on the stack left to right. The actual 134 // and arguments have been pushed on the stack left to right. The actual
116 // argument count matches the formal parameter count expected by the 135 // argument count matches the formal parameter count expected by the
117 // function. 136 // function.
118 // 137 //
119 // The live registers are: 138 // The live registers are:
120 // o r1: the JS function object being called (i.e., ourselves) 139 // o r1: the JS function object being called (i.e., ourselves)
121 // o cp: our context 140 // o cp: our context
122 // o pp: our caller's constant pool pointer (if FLAG_enable_ool_constant_pool) 141 // o pp: our caller's constant pool pointer (if FLAG_enable_ool_constant_pool)
123 // o fp: our caller's frame pointer 142 // o fp: our caller's frame pointer
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 191
173 info->set_prologue_offset(masm_->pc_offset()); 192 info->set_prologue_offset(masm_->pc_offset());
174 __ Prologue(BUILD_FUNCTION_FRAME); 193 __ Prologue(BUILD_FUNCTION_FRAME);
175 info->AddNoFrameRange(0, masm_->pc_offset()); 194 info->AddNoFrameRange(0, masm_->pc_offset());
176 195
177 { Comment cmnt(masm_, "[ Allocate locals"); 196 { Comment cmnt(masm_, "[ Allocate locals");
178 int locals_count = info->scope()->num_stack_slots(); 197 int locals_count = info->scope()->num_stack_slots();
179 // Generators allocate locals, if any, in context slots. 198 // Generators allocate locals, if any, in context slots.
180 ASSERT(!info->function()->is_generator() || locals_count == 0); 199 ASSERT(!info->function()->is_generator() || locals_count == 0);
181 if (locals_count > 0) { 200 if (locals_count > 0) {
182 // Emit a loop to initialize stack cells for locals when optimizing for 201 if (locals_count >= 128) {
183 // size. Otherwise, unroll the loop for maximum performance. 202 EmitStackCheck(masm_, r2, locals_count, r9);
203 }
184 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex); 204 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
185 if (FLAG_optimize_for_size && locals_count > 4) { 205 int kMaxPushes = FLAG_optimize_for_size ? 4 : 32;
186 Label loop; 206 if (locals_count >= kMaxPushes) {
187 __ mov(r2, Operand(locals_count)); 207 int loop_iterations = locals_count / kMaxPushes;
188 __ bind(&loop); 208 __ mov(r2, Operand(loop_iterations));
189 __ sub(r2, r2, Operand(1), SetCC); 209 Label loop_header;
190 __ push(r9); 210 __ bind(&loop_header);
191 __ b(&loop, ne); 211 // Do pushes.
192 } else { 212 for (int i = 0; i < kMaxPushes; i++) {
193 for (int i = 0; i < locals_count; i++) {
194 __ push(r9); 213 __ push(r9);
195 } 214 }
215 // Continue loop if not done.
216 __ sub(r2, r2, Operand(1), SetCC);
217 __ b(&loop_header, ne);
218 }
219 int remaining = locals_count % kMaxPushes;
220 // Emit the remaining pushes.
221 for (int i = 0; i < remaining; i++) {
222 __ push(r9);
196 } 223 }
197 } 224 }
198 } 225 }
199 226
200 bool function_in_register = true; 227 bool function_in_register = true;
201 228
202 // Possibly allocate a local context. 229 // Possibly allocate a local context.
203 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 230 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
204 if (heap_slots > 0) { 231 if (heap_slots > 0) {
205 // Argument to NewContext is the function, which is still in r1. 232 // Argument to NewContext is the function, which is still in r1.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 ASSERT(function->proxy()->var()->mode() == CONST || 323 ASSERT(function->proxy()->var()->mode() == CONST ||
297 function->proxy()->var()->mode() == CONST_LEGACY); 324 function->proxy()->var()->mode() == CONST_LEGACY);
298 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); 325 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
299 VisitVariableDeclaration(function); 326 VisitVariableDeclaration(function);
300 } 327 }
301 VisitDeclarations(scope()->declarations()); 328 VisitDeclarations(scope()->declarations());
302 } 329 }
303 330
304 { Comment cmnt(masm_, "[ Stack check"); 331 { Comment cmnt(masm_, "[ Stack check");
305 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 332 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
306 Label ok; 333 EmitStackCheck(masm_, ip);
307 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
308 __ cmp(sp, Operand(ip));
309 __ b(hs, &ok);
310 PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize);
311 __ Call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
312 __ bind(&ok);
313 } 334 }
314 335
315 { Comment cmnt(masm_, "[ Body"); 336 { Comment cmnt(masm_, "[ Body");
316 ASSERT(loop_depth() == 0); 337 ASSERT(loop_depth() == 0);
317 VisitStatements(function()->body()); 338 VisitStatements(function()->body());
318 ASSERT(loop_depth() == 0); 339 ASSERT(loop_depth() == 0);
319 } 340 }
320 } 341 }
321 342
322 // Always emit a 'return undefined' in case control fell off the end of 343 // Always emit a 'return undefined' in case control fell off the end of
(...skipping 4599 matching lines...) Expand 10 before | Expand all | Expand 10 after
4922 4943
4923 ASSERT(interrupt_address == 4944 ASSERT(interrupt_address ==
4924 isolate->builtins()->OsrAfterStackCheck()->entry()); 4945 isolate->builtins()->OsrAfterStackCheck()->entry());
4925 return OSR_AFTER_STACK_CHECK; 4946 return OSR_AFTER_STACK_CHECK;
4926 } 4947 }
4927 4948
4928 4949
4929 } } // namespace v8::internal 4950 } } // namespace v8::internal
4930 4951
4931 #endif // V8_TARGET_ARCH_ARM 4952 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698