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

Side by Side Diff: src/ia32/deoptimizer-ia32.cc

Issue 10701054: Enable stub generation using Hydrogen/Lithium (again) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merge with latest Created 8 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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.h » ('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 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 if (value == 1) return i; 300 if (value == 1) return i;
301 } 301 }
302 } 302 }
303 UNREACHABLE(); 303 UNREACHABLE();
304 return -1; 304 return -1;
305 } 305 }
306 306
307 307
308 void Deoptimizer::DoComputeOsrOutputFrame() { 308 void Deoptimizer::DoComputeOsrOutputFrame() {
309 DeoptimizationInputData* data = DeoptimizationInputData::cast( 309 DeoptimizationInputData* data = DeoptimizationInputData::cast(
310 optimized_code_->deoptimization_data()); 310 compiled_code_->deoptimization_data());
311 unsigned ast_id = data->OsrAstId()->value(); 311 unsigned ast_id = data->OsrAstId()->value();
312 // TODO(kasperl): This should not be the bailout_id_. It should be 312 // TODO(kasperl): This should not be the bailout_id_. It should be
313 // the ast id. Confusing. 313 // the ast id. Confusing.
314 ASSERT(bailout_id_ == ast_id); 314 ASSERT(bailout_id_ == ast_id);
315 315
316 int bailout_id = LookupBailoutId(data, BailoutId(ast_id)); 316 int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
317 unsigned translation_index = data->TranslationIndex(bailout_id)->value(); 317 unsigned translation_index = data->TranslationIndex(bailout_id)->value();
318 ByteArray* translations = data->TranslationByteArray(); 318 ByteArray* translations = data->TranslationByteArray();
319 319
320 TranslationIterator iterator(translations, translation_index); 320 TranslationIterator iterator(translations, translation_index);
(...skipping 16 matching lines...) Expand all
337 USE(closure_id); 337 USE(closure_id);
338 ASSERT_EQ(Translation::kSelfLiteralId, closure_id); 338 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
339 unsigned height = iterator.Next(); 339 unsigned height = iterator.Next();
340 unsigned height_in_bytes = height * kPointerSize; 340 unsigned height_in_bytes = height * kPointerSize;
341 USE(height_in_bytes); 341 USE(height_in_bytes);
342 342
343 unsigned fixed_size = ComputeFixedSize(function_); 343 unsigned fixed_size = ComputeFixedSize(function_);
344 unsigned input_frame_size = input_->GetFrameSize(); 344 unsigned input_frame_size = input_->GetFrameSize();
345 ASSERT(fixed_size + height_in_bytes == input_frame_size); 345 ASSERT(fixed_size + height_in_bytes == input_frame_size);
346 346
347 unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize; 347 unsigned stack_slot_size = compiled_code_->stack_slots() * kPointerSize;
348 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value(); 348 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
349 unsigned outgoing_size = outgoing_height * kPointerSize; 349 unsigned outgoing_size = outgoing_height * kPointerSize;
350 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size; 350 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
351 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call. 351 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call.
352 352
353 if (FLAG_trace_osr) { 353 if (FLAG_trace_osr) {
354 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ", 354 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ",
355 reinterpret_cast<intptr_t>(function_)); 355 reinterpret_cast<intptr_t>(function_));
356 function_->PrintName(); 356 function_->PrintName();
357 PrintF(" => node=%u, frame=%d->%d, ebp:esp=0x%08x:0x%08x]\n", 357 PrintF(" => node=%u, frame=%d->%d, ebp:esp=0x%08x:0x%08x]\n",
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 delete output_[0]; 448 delete output_[0];
449 output_[0] = input_; 449 output_[0] = input_;
450 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); 450 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_));
451 } else { 451 } else {
452 // Set up the frame pointer and the context pointer. 452 // Set up the frame pointer and the context pointer.
453 output_[0]->SetRegister(ebp.code(), frame_pointer); 453 output_[0]->SetRegister(ebp.code(), frame_pointer);
454 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); 454 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code()));
455 455
456 unsigned pc_offset = data->OsrPcOffset()->value(); 456 unsigned pc_offset = data->OsrPcOffset()->value();
457 uint32_t pc = reinterpret_cast<uint32_t>( 457 uint32_t pc = reinterpret_cast<uint32_t>(
458 optimized_code_->entry() + pc_offset); 458 compiled_code_->entry() + pc_offset);
459 output_[0]->SetPc(pc); 459 output_[0]->SetPc(pc);
460 } 460 }
461 Code* continuation = 461 Code* continuation =
462 function_->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); 462 function_->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
463 output_[0]->SetContinuation( 463 output_[0]->SetContinuation(
464 reinterpret_cast<uint32_t>(continuation->entry())); 464 reinterpret_cast<uint32_t>(continuation->entry()));
465 465
466 if (FLAG_trace_osr) { 466 if (FLAG_trace_osr) {
467 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", 467 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
468 ok ? "finished" : "aborted", 468 ok ? "finished" : "aborted",
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 Builtins* builtins = isolate_->builtins(); 562 Builtins* builtins = isolate_->builtins();
563 Code* adaptor_trampoline = 563 Code* adaptor_trampoline =
564 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); 564 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
565 uint32_t pc = reinterpret_cast<uint32_t>( 565 uint32_t pc = reinterpret_cast<uint32_t>(
566 adaptor_trampoline->instruction_start() + 566 adaptor_trampoline->instruction_start() +
567 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); 567 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
568 output_frame->SetPc(pc); 568 output_frame->SetPc(pc);
569 } 569 }
570 570
571 571
572 void Deoptimizer::DoCompiledStubFrame(TranslationIterator* iterator,
573 int frame_index) {
574 //
575 // FROM TO <-ebp
576 // | .... | | .... |
577 // +-------------------------+ +-------------------------+
578 // | JSFunction continuation | | JSFunction continuation |
579 // +-------------------------+ +-------------------------+<-esp
580 // | | saved frame (ebp) |
581 // | +=========================+<-ebp
582 // | | JSFunction context |
583 // v +-------------------------+
584 // | COMPILED_STUB marker | ebp = saved frame
585 // +-------------------------+ esi = JSFunction context
586 // | |
587 // | ... |
588 // | |
589 // +-------------------------+<-esp
590 //
591 //
592 int output_frame_size = 1 * kPointerSize;
593 FrameDescription* output_frame =
594 new(output_frame_size) FrameDescription(output_frame_size, 0);
595 Code* notify_miss =
596 isolate_->builtins()->builtin(Builtins::kNotifyICMiss);
597 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
598 output_frame->SetContinuation(
599 reinterpret_cast<uint32_t>(notify_miss->entry()));
600
601 ASSERT(compiled_code_->kind() == Code::COMPILED_STUB);
602 int major_key = compiled_code_->major_key();
603 CodeStubInterfaceDescriptor* descriptor =
604 isolate_->code_stub_interface_descriptors()[major_key];
605 Handle<Code> miss_ic(descriptor->deoptimization_handler);
606 output_frame->SetPc(reinterpret_cast<intptr_t>(miss_ic->instruction_start()));
607 unsigned input_frame_size = input_->GetFrameSize();
608 intptr_t value = input_->GetFrameSlot(input_frame_size - kPointerSize);
609 output_frame->SetFrameSlot(0, value);
610 value = input_->GetFrameSlot(input_frame_size - 2 * kPointerSize);
611 output_frame->SetRegister(ebp.code(), value);
612 output_frame->SetFp(value);
613 value = input_->GetFrameSlot(input_frame_size - 3 * kPointerSize);
614 output_frame->SetRegister(esi.code(), value);
615
616 Translation::Opcode opcode =
617 static_cast<Translation::Opcode>(iterator->Next());
618 ASSERT(opcode == Translation::REGISTER);
619 USE(opcode);
620 int input_reg = iterator->Next();
621 intptr_t input_value = input_->GetRegister(input_reg);
622 output_frame->SetRegister(edx.code(), input_value);
623
624 int32_t next = iterator->Next();
625 opcode = static_cast<Translation::Opcode>(next);
626 ASSERT(opcode == Translation::REGISTER);
627 input_reg = iterator->Next();
628 input_value = input_->GetRegister(input_reg);
629 output_frame->SetRegister(ecx.code(), input_value);
630
631 ASSERT(frame_index == 0);
632 output_[frame_index] = output_frame;
633 }
634
635
572 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, 636 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
573 int frame_index) { 637 int frame_index) {
574 Builtins* builtins = isolate_->builtins(); 638 Builtins* builtins = isolate_->builtins();
575 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); 639 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
576 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 640 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
577 unsigned height = iterator->Next(); 641 unsigned height = iterator->Next();
578 unsigned height_in_bytes = height * kPointerSize; 642 unsigned height_in_bytes = height * kPointerSize;
579 if (FLAG_trace_deopt) { 643 if (FLAG_trace_deopt) {
580 PrintF(" translating construct stub => height=%d\n", height_in_bytes); 644 PrintF(" translating construct stub => height=%d\n", height_in_bytes);
581 } 645 }
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 1054 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
991 // Set the register values. The values are not important as there are no 1055 // Set the register values. The values are not important as there are no
992 // callee saved registers in JavaScript frames, so all registers are 1056 // callee saved registers in JavaScript frames, so all registers are
993 // spilled. Registers ebp and esp are set to the correct values though. 1057 // spilled. Registers ebp and esp are set to the correct values though.
994 1058
995 for (int i = 0; i < Register::kNumRegisters; i++) { 1059 for (int i = 0; i < Register::kNumRegisters; i++) {
996 input_->SetRegister(i, i * 4); 1060 input_->SetRegister(i, i * 4);
997 } 1061 }
998 input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp())); 1062 input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp()));
999 input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp())); 1063 input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp()));
1000 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) { 1064 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
1001 input_->SetDoubleRegister(i, 0.0); 1065 input_->SetDoubleRegister(i, 0.0);
1002 } 1066 }
1003 1067
1004 // Fill the frame content from the actual data on the frame. 1068 // Fill the frame content from the actual data on the frame.
1005 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { 1069 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
1006 input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); 1070 input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
1007 } 1071 }
1008 } 1072 }
1009 1073
1010 1074
1011 #define __ masm()-> 1075 #define __ masm()->
1012 1076
1013 void Deoptimizer::EntryGenerator::Generate() { 1077 void Deoptimizer::EntryGenerator::Generate() {
1014 GeneratePrologue(); 1078 GeneratePrologue();
1015 CpuFeatures::Scope scope(SSE2);
1016 1079
1017 Isolate* isolate = masm()->isolate(); 1080 Isolate* isolate = masm()->isolate();
1018 1081
1019 // Save all general purpose registers before messing with them. 1082 // Save all general purpose registers before messing with them.
1020 const int kNumberOfRegisters = Register::kNumRegisters; 1083 const int kNumberOfRegisters = Register::kNumRegisters;
1021 1084
1022 const int kDoubleRegsSize = kDoubleSize * 1085 const int kDoubleRegsSize = kDoubleSize *
1023 XMMRegister::kNumAllocatableRegisters; 1086 XMMRegister::kNumAllocatableRegisters;
1024 __ sub(esp, Immediate(kDoubleRegsSize)); 1087 __ sub(esp, Immediate(kDoubleRegsSize));
1025 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) { 1088 if (CpuFeatures::IsSupported(SSE2)) {
1026 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i); 1089 CpuFeatures::Scope scope(SSE2);
1027 int offset = i * kDoubleSize; 1090 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
1028 __ movdbl(Operand(esp, offset), xmm_reg); 1091 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
1092 int offset = i * kDoubleSize;
1093 __ movdbl(Operand(esp, offset), xmm_reg);
1094 }
1029 } 1095 }
1030 1096
1031 __ pushad(); 1097 __ pushad();
1032 1098
1033 const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize + 1099 const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize +
1034 kDoubleRegsSize; 1100 kDoubleRegsSize;
1035 1101
1036 // Get the bailout id from the stack. 1102 // Get the bailout id from the stack.
1037 __ mov(ebx, Operand(esp, kSavedRegistersAreaSize)); 1103 __ mov(ebx, Operand(esp, kSavedRegistersAreaSize));
1038 1104
(...skipping 27 matching lines...) Expand all
1066 // Preserve deoptimizer object in register eax and get the input 1132 // Preserve deoptimizer object in register eax and get the input
1067 // frame descriptor pointer. 1133 // frame descriptor pointer.
1068 __ mov(ebx, Operand(eax, Deoptimizer::input_offset())); 1134 __ mov(ebx, Operand(eax, Deoptimizer::input_offset()));
1069 1135
1070 // Fill in the input registers. 1136 // Fill in the input registers.
1071 for (int i = kNumberOfRegisters - 1; i >= 0; i--) { 1137 for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
1072 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 1138 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
1073 __ pop(Operand(ebx, offset)); 1139 __ pop(Operand(ebx, offset));
1074 } 1140 }
1075 1141
1076 // Fill in the double input registers.
1077 int double_regs_offset = FrameDescription::double_registers_offset(); 1142 int double_regs_offset = FrameDescription::double_registers_offset();
1078 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) { 1143 if (CpuFeatures::IsSupported(SSE2)) {
1079 int dst_offset = i * kDoubleSize + double_regs_offset; 1144 CpuFeatures::Scope scope(SSE2);
1080 int src_offset = i * kDoubleSize; 1145 // Fill in the double input registers.
1081 __ movdbl(xmm0, Operand(esp, src_offset)); 1146 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
1082 __ movdbl(Operand(ebx, dst_offset), xmm0); 1147 int dst_offset = i * kDoubleSize + double_regs_offset;
1148 int src_offset = i * kDoubleSize;
1149 __ movdbl(xmm0, Operand(esp, src_offset));
1150 __ movdbl(Operand(ebx, dst_offset), xmm0);
1151 }
1083 } 1152 }
1153 __ fninit();
1084 1154
1085 // Remove the bailout id and the double registers from the stack. 1155 // Remove the bailout id and the double registers from the stack.
1086 if (type() == EAGER) { 1156 if (type() == EAGER) {
1087 __ add(esp, Immediate(kDoubleRegsSize + kPointerSize)); 1157 __ add(esp, Immediate(kDoubleRegsSize + kPointerSize));
1088 } else { 1158 } else {
1089 __ add(esp, Immediate(kDoubleRegsSize + 2 * kPointerSize)); 1159 __ add(esp, Immediate(kDoubleRegsSize + 2 * kPointerSize));
1090 } 1160 }
1091 1161
1092 // Compute a pointer to the unwinding limit in register ecx; that is 1162 // Compute a pointer to the unwinding limit in register ecx; that is
1093 // the first stack slot not part of the input frame. 1163 // the first stack slot not part of the input frame.
1094 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset())); 1164 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset()));
1095 __ add(ecx, esp); 1165 __ add(ecx, esp);
1096 1166
1097 // Unwind the stack down to - but not including - the unwinding 1167 // Unwind the stack down to - but not including - the unwinding
1098 // limit and copy the contents of the activation frame to the input 1168 // limit and copy the contents of the activation frame to the input
1099 // frame description. 1169 // frame description.
1100 __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset())); 1170 __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset()));
1171 Label pop_loop_header;
1172 __ jmp(&pop_loop_header);
1101 Label pop_loop; 1173 Label pop_loop;
1102 __ bind(&pop_loop); 1174 __ bind(&pop_loop);
1103 __ pop(Operand(edx, 0)); 1175 __ pop(Operand(edx, 0));
1104 __ add(edx, Immediate(sizeof(uint32_t))); 1176 __ add(edx, Immediate(sizeof(uint32_t)));
1177 __ bind(&pop_loop_header);
1105 __ cmp(ecx, esp); 1178 __ cmp(ecx, esp);
1106 __ j(not_equal, &pop_loop); 1179 __ j(not_equal, &pop_loop);
1107 1180
1108 // Compute the output frame in the deoptimizer. 1181 // Compute the output frame in the deoptimizer.
1109 __ push(eax); 1182 __ push(eax);
1110 __ PrepareCallCFunction(1, ebx); 1183 __ PrepareCallCFunction(1, ebx);
1111 __ mov(Operand(esp, 0 * kPointerSize), eax); 1184 __ mov(Operand(esp, 0 * kPointerSize), eax);
1112 { 1185 {
1113 AllowExternalCallThatCantCauseGC scope(masm()); 1186 AllowExternalCallThatCantCauseGC scope(masm());
1114 __ CallCFunction( 1187 __ CallCFunction(
(...skipping 17 matching lines...) Expand all
1132 // If frame needs dynamic alignment push padding. 1205 // If frame needs dynamic alignment push padding.
1133 Label no_padding; 1206 Label no_padding;
1134 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), 1207 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
1135 Immediate(0)); 1208 Immediate(0));
1136 __ j(equal, &no_padding); 1209 __ j(equal, &no_padding);
1137 __ push(Immediate(kAlignmentZapValue)); 1210 __ push(Immediate(kAlignmentZapValue));
1138 __ bind(&no_padding); 1211 __ bind(&no_padding);
1139 } 1212 }
1140 1213
1141 // Replace the current frame with the output frames. 1214 // Replace the current frame with the output frames.
1142 Label outer_push_loop, inner_push_loop; 1215 Label outer_push_loop, inner_push_loop,
1216 outer_loop_header, inner_loop_header;
1143 // Outer loop state: eax = current FrameDescription**, edx = one past the 1217 // Outer loop state: eax = current FrameDescription**, edx = one past the
1144 // last FrameDescription**. 1218 // last FrameDescription**.
1145 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); 1219 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset()));
1146 __ mov(eax, Operand(eax, Deoptimizer::output_offset())); 1220 __ mov(eax, Operand(eax, Deoptimizer::output_offset()));
1147 __ lea(edx, Operand(eax, edx, times_4, 0)); 1221 __ lea(edx, Operand(eax, edx, times_4, 0));
1222 __ jmp(&outer_loop_header);
1148 __ bind(&outer_push_loop); 1223 __ bind(&outer_push_loop);
1149 // Inner loop state: ebx = current FrameDescription*, ecx = loop index. 1224 // Inner loop state: ebx = current FrameDescription*, ecx = loop index.
1150 __ mov(ebx, Operand(eax, 0)); 1225 __ mov(ebx, Operand(eax, 0));
1151 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset())); 1226 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset()));
1227 __ jmp(&inner_loop_header);
1152 __ bind(&inner_push_loop); 1228 __ bind(&inner_push_loop);
1153 __ sub(ecx, Immediate(sizeof(uint32_t))); 1229 __ sub(ecx, Immediate(sizeof(uint32_t)));
1154 __ push(Operand(ebx, ecx, times_1, FrameDescription::frame_content_offset())); 1230 __ push(Operand(ebx, ecx, times_1, FrameDescription::frame_content_offset()));
1231 __ bind(&inner_loop_header);
1155 __ test(ecx, ecx); 1232 __ test(ecx, ecx);
1156 __ j(not_zero, &inner_push_loop); 1233 __ j(not_zero, &inner_push_loop);
1157 __ add(eax, Immediate(kPointerSize)); 1234 __ add(eax, Immediate(kPointerSize));
1235 __ bind(&outer_loop_header);
1158 __ cmp(eax, edx); 1236 __ cmp(eax, edx);
1159 __ j(below, &outer_push_loop); 1237 __ j(below, &outer_push_loop);
1160 1238
1161 // In case of OSR, we have to restore the XMM registers. 1239 // In case of OSR, we have to restore the XMM registers.
1162 if (type() == OSR) { 1240 if (type() == OSR) {
1163 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) { 1241 if (CpuFeatures::IsSupported(SSE2)) {
1164 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i); 1242 CpuFeatures::Scope scope(SSE2);
1165 int src_offset = i * kDoubleSize + double_regs_offset; 1243 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
1166 __ movdbl(xmm_reg, Operand(ebx, src_offset)); 1244 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
1245 int src_offset = i * kDoubleSize + double_regs_offset;
1246 __ movdbl(xmm_reg, Operand(ebx, src_offset));
1247 }
1167 } 1248 }
1168 } 1249 }
1169 1250
1170 // Push state, pc, and continuation from the last output frame. 1251 // Push state, pc, and continuation from the last output frame.
1171 if (type() != OSR) { 1252 if (type() != OSR) {
1172 __ push(Operand(ebx, FrameDescription::state_offset())); 1253 __ push(Operand(ebx, FrameDescription::state_offset()));
1173 } 1254 }
1174 __ push(Operand(ebx, FrameDescription::pc_offset())); 1255 __ push(Operand(ebx, FrameDescription::pc_offset()));
1175 __ push(Operand(ebx, FrameDescription::continuation_offset())); 1256 __ push(Operand(ebx, FrameDescription::continuation_offset()));
1176 1257
(...skipping 24 matching lines...) Expand all
1201 } 1282 }
1202 __ bind(&done); 1283 __ bind(&done);
1203 } 1284 }
1204 1285
1205 #undef __ 1286 #undef __
1206 1287
1207 1288
1208 } } // namespace v8::internal 1289 } } // namespace v8::internal
1209 1290
1210 #endif // V8_TARGET_ARCH_IA32 1291 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698