| OLD | NEW |
| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 FrameScope frame_scope(masm_, StackFrame::MANUAL); | 137 FrameScope frame_scope(masm_, StackFrame::MANUAL); |
| 138 | 138 |
| 139 info->set_prologue_offset(masm_->pc_offset()); | 139 info->set_prologue_offset(masm_->pc_offset()); |
| 140 __ Prologue(info->IsCodePreAgingActive()); | 140 __ Prologue(info->IsCodePreAgingActive()); |
| 141 info->AddNoFrameRange(0, masm_->pc_offset()); | 141 info->AddNoFrameRange(0, masm_->pc_offset()); |
| 142 | 142 |
| 143 { Comment cmnt(masm_, "[ Allocate locals"); | 143 { Comment cmnt(masm_, "[ Allocate locals"); |
| 144 int locals_count = info->scope()->num_stack_slots(); | 144 int locals_count = info->scope()->num_stack_slots(); |
| 145 // Generators allocate locals, if any, in context slots. | 145 // Generators allocate locals, if any, in context slots. |
| 146 DCHECK(!info->function()->is_generator() || locals_count == 0); | 146 DCHECK(!info->function()->is_generator() || locals_count == 0); |
| 147 if (locals_count == 1) { | 147 AllocateLocals(locals_count); |
| 148 __ push(Immediate(isolate()->factory()->undefined_value())); | |
| 149 } else if (locals_count > 1) { | |
| 150 if (locals_count >= 128) { | |
| 151 Label ok; | |
| 152 __ mov(ecx, esp); | |
| 153 __ sub(ecx, Immediate(locals_count * kPointerSize)); | |
| 154 ExternalReference stack_limit = | |
| 155 ExternalReference::address_of_real_stack_limit(isolate()); | |
| 156 __ cmp(ecx, Operand::StaticVariable(stack_limit)); | |
| 157 __ j(above_equal, &ok, Label::kNear); | |
| 158 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | |
| 159 __ bind(&ok); | |
| 160 } | |
| 161 __ mov(eax, Immediate(isolate()->factory()->undefined_value())); | |
| 162 const int kMaxPushes = 32; | |
| 163 if (locals_count >= kMaxPushes) { | |
| 164 int loop_iterations = locals_count / kMaxPushes; | |
| 165 __ mov(ecx, loop_iterations); | |
| 166 Label loop_header; | |
| 167 __ bind(&loop_header); | |
| 168 // Do pushes. | |
| 169 for (int i = 0; i < kMaxPushes; i++) { | |
| 170 __ push(eax); | |
| 171 } | |
| 172 __ dec(ecx); | |
| 173 __ j(not_zero, &loop_header, Label::kNear); | |
| 174 } | |
| 175 int remaining = locals_count % kMaxPushes; | |
| 176 // Emit the remaining pushes. | |
| 177 for (int i = 0; i < remaining; i++) { | |
| 178 __ push(eax); | |
| 179 } | |
| 180 } | |
| 181 } | 148 } |
| 182 | 149 |
| 183 bool function_in_register = true; | 150 bool function_in_register = true; |
| 184 | 151 |
| 185 // Possibly allocate a local context. | 152 // Possibly allocate a local context. |
| 186 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 153 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 187 if (heap_slots > 0) { | 154 if (heap_slots > 0) { |
| 188 Comment cmnt(masm_, "[ Allocate context"); | 155 Comment cmnt(masm_, "[ Allocate context"); |
| 189 bool need_write_barrier = true; | 156 bool need_write_barrier = true; |
| 190 // Argument to NewContext is the function, which is still in edi. | 157 // Argument to NewContext is the function, which is still in edi. |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 | 282 |
| 316 // Always emit a 'return undefined' in case control fell off the end of | 283 // Always emit a 'return undefined' in case control fell off the end of |
| 317 // the body. | 284 // the body. |
| 318 { Comment cmnt(masm_, "[ return <undefined>;"); | 285 { Comment cmnt(masm_, "[ return <undefined>;"); |
| 319 __ mov(eax, isolate()->factory()->undefined_value()); | 286 __ mov(eax, isolate()->factory()->undefined_value()); |
| 320 EmitReturnSequence(); | 287 EmitReturnSequence(); |
| 321 } | 288 } |
| 322 } | 289 } |
| 323 | 290 |
| 324 | 291 |
| 292 void FullCodeGenerator::AllocateLocals(int locals_count) { |
| 293 if (locals_count == 1) { |
| 294 __ push(Immediate(isolate()->factory()->undefined_value())); |
| 295 } else if (locals_count > 1) { |
| 296 if (locals_count >= 128) { |
| 297 Label ok; |
| 298 __ mov(ecx, esp); |
| 299 __ sub(ecx, Immediate(locals_count * kPointerSize)); |
| 300 ExternalReference stack_limit = |
| 301 ExternalReference::address_of_real_stack_limit(isolate()); |
| 302 __ cmp(ecx, Operand::StaticVariable(stack_limit)); |
| 303 __ j(above_equal, &ok, Label::kNear); |
| 304 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); |
| 305 __ bind(&ok); |
| 306 } |
| 307 __ mov(eax, Immediate(isolate()->factory()->undefined_value())); |
| 308 const int kMaxPushes = 32; |
| 309 if (locals_count >= kMaxPushes) { |
| 310 int loop_iterations = locals_count / kMaxPushes; |
| 311 __ mov(ecx, loop_iterations); |
| 312 Label loop_header; |
| 313 __ bind(&loop_header); |
| 314 // Do pushes. |
| 315 for (int i = 0; i < kMaxPushes; i++) { |
| 316 __ push(eax); |
| 317 } |
| 318 __ dec(ecx); |
| 319 __ j(not_zero, &loop_header, Label::kNear); |
| 320 } |
| 321 int remaining = locals_count % kMaxPushes; |
| 322 // Emit the remaining pushes. |
| 323 for (int i = 0; i < remaining; i++) { |
| 324 __ push(eax); |
| 325 } |
| 326 } |
| 327 } |
| 328 |
| 329 |
| 330 void FullCodeGenerator::DeallocateLocals(int local_count) { |
| 331 if (local_count > 0) { |
| 332 __ add(esp, Immediate(local_count * kPointerSize)); |
| 333 } |
| 334 } |
| 335 |
| 336 |
| 325 void FullCodeGenerator::ClearAccumulator() { | 337 void FullCodeGenerator::ClearAccumulator() { |
| 326 __ Move(eax, Immediate(Smi::FromInt(0))); | 338 __ Move(eax, Immediate(Smi::FromInt(0))); |
| 327 } | 339 } |
| 328 | 340 |
| 329 | 341 |
| 330 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { | 342 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { |
| 331 __ mov(ebx, Immediate(profiling_counter_)); | 343 __ mov(ebx, Immediate(profiling_counter_)); |
| 332 __ sub(FieldOperand(ebx, Cell::kValueOffset), | 344 __ sub(FieldOperand(ebx, Cell::kValueOffset), |
| 333 Immediate(Smi::FromInt(delta))); | 345 Immediate(Smi::FromInt(delta))); |
| 334 } | 346 } |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 __ j(cc, if_true); | 670 __ j(cc, if_true); |
| 659 __ jmp(if_false); | 671 __ jmp(if_false); |
| 660 } | 672 } |
| 661 } | 673 } |
| 662 | 674 |
| 663 | 675 |
| 664 MemOperand FullCodeGenerator::StackOperand(Variable* var) { | 676 MemOperand FullCodeGenerator::StackOperand(Variable* var) { |
| 665 DCHECK(var->IsStackAllocated()); | 677 DCHECK(var->IsStackAllocated()); |
| 666 // Offset is negative because higher indexes are at lower addresses. | 678 // Offset is negative because higher indexes are at lower addresses. |
| 667 int offset = -var->index() * kPointerSize; | 679 int offset = -var->index() * kPointerSize; |
| 680 Scope* var_scope = var->scope(); |
| 681 while (!var_scope->is_function_scope() && !var_scope->is_script_scope()) { |
| 682 var_scope = var_scope->outer_scope(); |
| 683 offset -= var_scope->num_stack_slots() * kPointerSize; |
| 684 } |
| 668 // Adjust by a (parameter or local) base offset. | 685 // Adjust by a (parameter or local) base offset. |
| 669 if (var->IsParameter()) { | 686 if (var->IsParameter()) { |
| 670 offset += (info_->scope()->num_parameters() + 1) * kPointerSize; | 687 offset += (info_->scope()->num_parameters() + 1) * kPointerSize; |
| 671 } else { | 688 } else { |
| 672 offset += JavaScriptFrameConstants::kLocal0Offset; | 689 offset += JavaScriptFrameConstants::kLocal0Offset; |
| 673 } | 690 } |
| 674 return Operand(ebp, offset); | 691 return Operand(ebp, offset); |
| 675 } | 692 } |
| 676 | 693 |
| 677 | 694 |
| (...skipping 4498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5176 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5193 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 5177 Assembler::target_address_at(call_target_address, | 5194 Assembler::target_address_at(call_target_address, |
| 5178 unoptimized_code)); | 5195 unoptimized_code)); |
| 5179 return OSR_AFTER_STACK_CHECK; | 5196 return OSR_AFTER_STACK_CHECK; |
| 5180 } | 5197 } |
| 5181 | 5198 |
| 5182 | 5199 |
| 5183 } } // namespace v8::internal | 5200 } } // namespace v8::internal |
| 5184 | 5201 |
| 5185 #endif // V8_TARGET_ARCH_IA32 | 5202 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |