OLD | NEW |
---|---|
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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 // o esp: stack pointer (pointing to return address) | 112 // o esp: stack pointer (pointing to return address) |
113 // | 113 // |
114 // The function builds a JS frame. Please see JavaScriptFrameConstants in | 114 // The function builds a JS frame. Please see JavaScriptFrameConstants in |
115 // frames-ia32.h for its layout. | 115 // frames-ia32.h for its layout. |
116 void FullCodeGenerator::Generate(CompilationInfo* info) { | 116 void FullCodeGenerator::Generate(CompilationInfo* info) { |
117 ASSERT(info_ == NULL); | 117 ASSERT(info_ == NULL); |
118 info_ = info; | 118 info_ = info; |
119 scope_ = info->scope(); | 119 scope_ = info->scope(); |
120 handler_table_ = | 120 handler_table_ = |
121 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); | 121 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); |
122 profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell( | |
123 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget))); | |
122 SetFunctionPosition(function()); | 124 SetFunctionPosition(function()); |
123 Comment cmnt(masm_, "[ function compiled by full code generator"); | 125 Comment cmnt(masm_, "[ function compiled by full code generator"); |
124 | 126 |
125 #ifdef DEBUG | 127 #ifdef DEBUG |
126 if (strlen(FLAG_stop_at) > 0 && | 128 if (strlen(FLAG_stop_at) > 0 && |
127 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { | 129 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
128 __ int3(); | 130 __ int3(); |
129 } | 131 } |
130 #endif | 132 #endif |
131 | 133 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 EmitReturnSequence(); | 318 EmitReturnSequence(); |
317 } | 319 } |
318 } | 320 } |
319 | 321 |
320 | 322 |
321 void FullCodeGenerator::ClearAccumulator() { | 323 void FullCodeGenerator::ClearAccumulator() { |
322 __ Set(eax, Immediate(Smi::FromInt(0))); | 324 __ Set(eax, Immediate(Smi::FromInt(0))); |
323 } | 325 } |
324 | 326 |
325 | 327 |
326 void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) { | 328 void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt, |
329 Label* back_edge_target) { | |
327 Comment cmnt(masm_, "[ Stack check"); | 330 Comment cmnt(masm_, "[ Stack check"); |
328 Label ok; | 331 Label ok; |
329 ExternalReference stack_limit = | 332 |
330 ExternalReference::address_of_stack_limit(isolate()); | 333 if (FLAG_count_based_interrupts) { |
331 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 334 if (FLAG_weighted_back_edges) { |
332 __ j(above_equal, &ok, Label::kNear); | 335 ASSERT(back_edge_target->is_bound()); |
333 StackCheckStub stub; | 336 int distance = masm_->pc_offset() - back_edge_target->pos(); |
334 __ CallStub(&stub); | 337 __ sub(Operand::Cell(profiling_counter_), |
Vyacheslav Egorov (Chromium)
2012/02/14 12:52:47
generation of the sub can be moved out of the if a
Jakob Kummerow
2012/02/14 13:54:45
Done.
| |
338 // weight: ceil(distance/100). | |
339 Immediate(Smi::FromInt(Min(127, (distance + 99) / 100)))); | |
340 } else { | |
341 __ sub(Operand::Cell(profiling_counter_), Immediate(Smi::FromInt(1))); | |
342 } | |
343 __ j(positive, &ok, Label::kNear); | |
344 InterruptStub stub; | |
345 __ CallStub(&stub); | |
346 } else { | |
347 ExternalReference stack_limit = | |
Vyacheslav Egorov (Chromium)
2012/02/14 12:52:47
It is not clear to me why stack check sits in the
Jakob Kummerow
2012/02/14 13:54:45
Done.
| |
348 ExternalReference::address_of_stack_limit(isolate()); | |
349 __ cmp(esp, Operand::StaticVariable(stack_limit)); | |
350 __ j(above_equal, &ok, Label::kNear); | |
351 StackCheckStub stub; | |
352 __ CallStub(&stub); | |
353 } | |
354 | |
335 // Record a mapping of this PC offset to the OSR id. This is used to find | 355 // Record a mapping of this PC offset to the OSR id. This is used to find |
336 // the AST id from the unoptimized code in order to use it as a key into | 356 // the AST id from the unoptimized code in order to use it as a key into |
337 // the deoptimization input data found in the optimized code. | 357 // the deoptimization input data found in the optimized code. |
338 RecordStackCheck(stmt->OsrEntryId()); | 358 RecordStackCheck(stmt->OsrEntryId()); |
339 | 359 |
340 // Loop stack checks can be patched to perform on-stack replacement. In | 360 // Loop stack checks can be patched to perform on-stack replacement. In |
341 // order to decide whether or not to perform OSR we embed the loop depth | 361 // order to decide whether or not to perform OSR we embed the loop depth |
342 // in a test instruction after the call so we can extract it from the OSR | 362 // in a test instruction after the call so we can extract it from the OSR |
343 // builtin. | 363 // builtin. |
344 ASSERT(loop_depth() > 0); | 364 ASSERT(loop_depth() > 0); |
345 __ test(eax, Immediate(Min(loop_depth(), Code::kMaxLoopNestingMarker))); | 365 __ test(eax, Immediate(Min(loop_depth(), Code::kMaxLoopNestingMarker))); |
346 | 366 |
367 if (FLAG_count_based_interrupts) { | |
368 // Reset the countdown. | |
369 __ mov(Operand::Cell(profiling_counter_), | |
370 Immediate(Smi::FromInt(FLAG_interrupt_budget))); | |
371 } | |
372 | |
347 __ bind(&ok); | 373 __ bind(&ok); |
348 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 374 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); |
349 // Record a mapping of the OSR id to this PC. This is used if the OSR | 375 // Record a mapping of the OSR id to this PC. This is used if the OSR |
350 // entry becomes the target of a bailout. We don't expect it to be, but | 376 // entry becomes the target of a bailout. We don't expect it to be, but |
351 // we want it to work if it is. | 377 // we want it to work if it is. |
352 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); | 378 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); |
353 } | 379 } |
354 | 380 |
355 | 381 |
356 void FullCodeGenerator::EmitReturnSequence() { | 382 void FullCodeGenerator::EmitReturnSequence() { |
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1054 } | 1080 } |
1055 | 1081 |
1056 // Generate code for the body of the loop. | 1082 // Generate code for the body of the loop. |
1057 Visit(stmt->body()); | 1083 Visit(stmt->body()); |
1058 | 1084 |
1059 // Generate code for going to the next element by incrementing the | 1085 // Generate code for going to the next element by incrementing the |
1060 // index (smi) stored on top of the stack. | 1086 // index (smi) stored on top of the stack. |
1061 __ bind(loop_statement.continue_label()); | 1087 __ bind(loop_statement.continue_label()); |
1062 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); | 1088 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); |
1063 | 1089 |
1064 EmitStackCheck(stmt); | 1090 EmitStackCheck(stmt, &loop); |
1065 __ jmp(&loop); | 1091 __ jmp(&loop); |
1066 | 1092 |
1067 // Remove the pointers stored on the stack. | 1093 // Remove the pointers stored on the stack. |
1068 __ bind(loop_statement.break_label()); | 1094 __ bind(loop_statement.break_label()); |
1069 __ add(esp, Immediate(5 * kPointerSize)); | 1095 __ add(esp, Immediate(5 * kPointerSize)); |
1070 | 1096 |
1071 // Exit and decrement the loop depth. | 1097 // Exit and decrement the loop depth. |
1072 __ bind(&exit); | 1098 __ bind(&exit); |
1073 decrement_loop_depth(); | 1099 decrement_loop_depth(); |
1074 } | 1100 } |
(...skipping 3326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4401 *context_length = 0; | 4427 *context_length = 0; |
4402 return previous_; | 4428 return previous_; |
4403 } | 4429 } |
4404 | 4430 |
4405 | 4431 |
4406 #undef __ | 4432 #undef __ |
4407 | 4433 |
4408 } } // namespace v8::internal | 4434 } } // namespace v8::internal |
4409 | 4435 |
4410 #endif // V8_TARGET_ARCH_IA32 | 4436 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |