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

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

Issue 11414262: Revert 13105: "Enable stub generation using Hydrogen/Lithium." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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 compiled_code_->deoptimization_data()); 310 optimized_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 = compiled_code_->stack_slots() * kPointerSize; 347 unsigned stack_slot_size = optimized_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 compiled_code_->entry() + pc_offset); 458 optimized_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
636 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, 572 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
637 int frame_index) { 573 int frame_index) {
638 Builtins* builtins = isolate_->builtins(); 574 Builtins* builtins = isolate_->builtins();
639 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); 575 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
640 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 576 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
641 unsigned height = iterator->Next(); 577 unsigned height = iterator->Next();
642 unsigned height_in_bytes = height * kPointerSize; 578 unsigned height_in_bytes = height * kPointerSize;
643 if (FLAG_trace_deopt) { 579 if (FLAG_trace_deopt) {
644 PrintF(" translating construct stub => height=%d\n", height_in_bytes); 580 PrintF(" translating construct stub => height=%d\n", height_in_bytes);
645 } 581 }
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 990 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
1055 // Set the register values. The values are not important as there are no 991 // Set the register values. The values are not important as there are no
1056 // callee saved registers in JavaScript frames, so all registers are 992 // callee saved registers in JavaScript frames, so all registers are
1057 // spilled. Registers ebp and esp are set to the correct values though. 993 // spilled. Registers ebp and esp are set to the correct values though.
1058 994
1059 for (int i = 0; i < Register::kNumRegisters; i++) { 995 for (int i = 0; i < Register::kNumRegisters; i++) {
1060 input_->SetRegister(i, i * 4); 996 input_->SetRegister(i, i * 4);
1061 } 997 }
1062 input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp())); 998 input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp()));
1063 input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp())); 999 input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp()));
1064 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { 1000 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) {
1065 input_->SetDoubleRegister(i, 0.0); 1001 input_->SetDoubleRegister(i, 0.0);
1066 } 1002 }
1067 1003
1068 // Fill the frame content from the actual data on the frame. 1004 // Fill the frame content from the actual data on the frame.
1069 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { 1005 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
1070 input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); 1006 input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
1071 } 1007 }
1072 } 1008 }
1073 1009
1074 1010
1075 #define __ masm()-> 1011 #define __ masm()->
1076 1012
1077 void Deoptimizer::EntryGenerator::Generate() { 1013 void Deoptimizer::EntryGenerator::Generate() {
1078 GeneratePrologue(); 1014 GeneratePrologue();
1015 CpuFeatures::Scope scope(SSE2);
1079 1016
1080 Isolate* isolate = masm()->isolate(); 1017 Isolate* isolate = masm()->isolate();
1081 1018
1082 // Save all general purpose registers before messing with them. 1019 // Save all general purpose registers before messing with them.
1083 const int kNumberOfRegisters = Register::kNumRegisters; 1020 const int kNumberOfRegisters = Register::kNumRegisters;
1084 1021
1085 const int kDoubleRegsSize = kDoubleSize * 1022 const int kDoubleRegsSize = kDoubleSize *
1086 XMMRegister::kNumAllocatableRegisters; 1023 XMMRegister::kNumAllocatableRegisters;
1087 __ sub(esp, Immediate(kDoubleRegsSize)); 1024 __ sub(esp, Immediate(kDoubleRegsSize));
1088 if (CpuFeatures::IsSupported(SSE2)) { 1025 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
1089 CpuFeatures::Scope scope(SSE2); 1026 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
1090 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) { 1027 int offset = i * kDoubleSize;
1091 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i); 1028 __ movdbl(Operand(esp, offset), xmm_reg);
1092 int offset = i * kDoubleSize;
1093 __ movdbl(Operand(esp, offset), xmm_reg);
1094 }
1095 } 1029 }
1096 1030
1097 __ pushad(); 1031 __ pushad();
1098 1032
1099 const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize + 1033 const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize +
1100 kDoubleRegsSize; 1034 kDoubleRegsSize;
1101 1035
1102 // Get the bailout id from the stack. 1036 // Get the bailout id from the stack.
1103 __ mov(ebx, Operand(esp, kSavedRegistersAreaSize)); 1037 __ mov(ebx, Operand(esp, kSavedRegistersAreaSize));
1104 1038
(...skipping 27 matching lines...) Expand all
1132 // Preserve deoptimizer object in register eax and get the input 1066 // Preserve deoptimizer object in register eax and get the input
1133 // frame descriptor pointer. 1067 // frame descriptor pointer.
1134 __ mov(ebx, Operand(eax, Deoptimizer::input_offset())); 1068 __ mov(ebx, Operand(eax, Deoptimizer::input_offset()));
1135 1069
1136 // Fill in the input registers. 1070 // Fill in the input registers.
1137 for (int i = kNumberOfRegisters - 1; i >= 0; i--) { 1071 for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
1138 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 1072 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
1139 __ pop(Operand(ebx, offset)); 1073 __ pop(Operand(ebx, offset));
1140 } 1074 }
1141 1075
1076 // Fill in the double input registers.
1142 int double_regs_offset = FrameDescription::double_registers_offset(); 1077 int double_regs_offset = FrameDescription::double_registers_offset();
1143 if (CpuFeatures::IsSupported(SSE2)) { 1078 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
1144 CpuFeatures::Scope scope(SSE2); 1079 int dst_offset = i * kDoubleSize + double_regs_offset;
1145 // Fill in the double input registers. 1080 int src_offset = i * kDoubleSize;
1146 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) { 1081 __ movdbl(xmm0, Operand(esp, src_offset));
1147 int dst_offset = i * kDoubleSize + double_regs_offset; 1082 __ movdbl(Operand(ebx, dst_offset), xmm0);
1148 int src_offset = i * kDoubleSize;
1149 __ movdbl(xmm0, Operand(esp, src_offset));
1150 __ movdbl(Operand(ebx, dst_offset), xmm0);
1151 }
1152 } 1083 }
1153 __ fninit();
1154 1084
1155 // Remove the bailout id and the double registers from the stack. 1085 // Remove the bailout id and the double registers from the stack.
1156 if (type() == EAGER) { 1086 if (type() == EAGER) {
1157 __ add(esp, Immediate(kDoubleRegsSize + kPointerSize)); 1087 __ add(esp, Immediate(kDoubleRegsSize + kPointerSize));
1158 } else { 1088 } else {
1159 __ add(esp, Immediate(kDoubleRegsSize + 2 * kPointerSize)); 1089 __ add(esp, Immediate(kDoubleRegsSize + 2 * kPointerSize));
1160 } 1090 }
1161 1091
1162 // Compute a pointer to the unwinding limit in register ecx; that is 1092 // Compute a pointer to the unwinding limit in register ecx; that is
1163 // the first stack slot not part of the input frame. 1093 // the first stack slot not part of the input frame.
1164 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset())); 1094 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset()));
1165 __ add(ecx, esp); 1095 __ add(ecx, esp);
1166 1096
1167 // Unwind the stack down to - but not including - the unwinding 1097 // Unwind the stack down to - but not including - the unwinding
1168 // limit and copy the contents of the activation frame to the input 1098 // limit and copy the contents of the activation frame to the input
1169 // frame description. 1099 // frame description.
1170 __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset())); 1100 __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset()));
1171 Label pop_loop_header;
1172 __ jmp(&pop_loop_header);
1173 Label pop_loop; 1101 Label pop_loop;
1174 __ bind(&pop_loop); 1102 __ bind(&pop_loop);
1175 __ pop(Operand(edx, 0)); 1103 __ pop(Operand(edx, 0));
1176 __ add(edx, Immediate(sizeof(uint32_t))); 1104 __ add(edx, Immediate(sizeof(uint32_t)));
1177 __ bind(&pop_loop_header);
1178 __ cmp(ecx, esp); 1105 __ cmp(ecx, esp);
1179 __ j(not_equal, &pop_loop); 1106 __ j(not_equal, &pop_loop);
1180 1107
1181 // Compute the output frame in the deoptimizer. 1108 // Compute the output frame in the deoptimizer.
1182 __ push(eax); 1109 __ push(eax);
1183 __ PrepareCallCFunction(1, ebx); 1110 __ PrepareCallCFunction(1, ebx);
1184 __ mov(Operand(esp, 0 * kPointerSize), eax); 1111 __ mov(Operand(esp, 0 * kPointerSize), eax);
1185 { 1112 {
1186 AllowExternalCallThatCantCauseGC scope(masm()); 1113 AllowExternalCallThatCantCauseGC scope(masm());
1187 __ CallCFunction( 1114 __ CallCFunction(
(...skipping 17 matching lines...) Expand all
1205 // If frame needs dynamic alignment push padding. 1132 // If frame needs dynamic alignment push padding.
1206 Label no_padding; 1133 Label no_padding;
1207 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), 1134 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
1208 Immediate(0)); 1135 Immediate(0));
1209 __ j(equal, &no_padding); 1136 __ j(equal, &no_padding);
1210 __ push(Immediate(kAlignmentZapValue)); 1137 __ push(Immediate(kAlignmentZapValue));
1211 __ bind(&no_padding); 1138 __ bind(&no_padding);
1212 } 1139 }
1213 1140
1214 // Replace the current frame with the output frames. 1141 // Replace the current frame with the output frames.
1215 Label outer_push_loop, inner_push_loop, 1142 Label outer_push_loop, inner_push_loop;
1216 outer_loop_header, inner_loop_header;
1217 // Outer loop state: eax = current FrameDescription**, edx = one past the 1143 // Outer loop state: eax = current FrameDescription**, edx = one past the
1218 // last FrameDescription**. 1144 // last FrameDescription**.
1219 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); 1145 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset()));
1220 __ mov(eax, Operand(eax, Deoptimizer::output_offset())); 1146 __ mov(eax, Operand(eax, Deoptimizer::output_offset()));
1221 __ lea(edx, Operand(eax, edx, times_4, 0)); 1147 __ lea(edx, Operand(eax, edx, times_4, 0));
1222 __ jmp(&outer_loop_header);
1223 __ bind(&outer_push_loop); 1148 __ bind(&outer_push_loop);
1224 // Inner loop state: ebx = current FrameDescription*, ecx = loop index. 1149 // Inner loop state: ebx = current FrameDescription*, ecx = loop index.
1225 __ mov(ebx, Operand(eax, 0)); 1150 __ mov(ebx, Operand(eax, 0));
1226 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset())); 1151 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset()));
1227 __ jmp(&inner_loop_header);
1228 __ bind(&inner_push_loop); 1152 __ bind(&inner_push_loop);
1229 __ sub(ecx, Immediate(sizeof(uint32_t))); 1153 __ sub(ecx, Immediate(sizeof(uint32_t)));
1230 __ push(Operand(ebx, ecx, times_1, FrameDescription::frame_content_offset())); 1154 __ push(Operand(ebx, ecx, times_1, FrameDescription::frame_content_offset()));
1231 __ bind(&inner_loop_header);
1232 __ test(ecx, ecx); 1155 __ test(ecx, ecx);
1233 __ j(not_zero, &inner_push_loop); 1156 __ j(not_zero, &inner_push_loop);
1234 __ add(eax, Immediate(kPointerSize)); 1157 __ add(eax, Immediate(kPointerSize));
1235 __ bind(&outer_loop_header);
1236 __ cmp(eax, edx); 1158 __ cmp(eax, edx);
1237 __ j(below, &outer_push_loop); 1159 __ j(below, &outer_push_loop);
1238 1160
1239 // In case of OSR, we have to restore the XMM registers. 1161 // In case of OSR, we have to restore the XMM registers.
1240 if (type() == OSR) { 1162 if (type() == OSR) {
1241 if (CpuFeatures::IsSupported(SSE2)) { 1163 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
1242 CpuFeatures::Scope scope(SSE2); 1164 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
1243 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) { 1165 int src_offset = i * kDoubleSize + double_regs_offset;
1244 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i); 1166 __ movdbl(xmm_reg, Operand(ebx, src_offset));
1245 int src_offset = i * kDoubleSize + double_regs_offset;
1246 __ movdbl(xmm_reg, Operand(ebx, src_offset));
1247 }
1248 } 1167 }
1249 } 1168 }
1250 1169
1251 // Push state, pc, and continuation from the last output frame. 1170 // Push state, pc, and continuation from the last output frame.
1252 if (type() != OSR) { 1171 if (type() != OSR) {
1253 __ push(Operand(ebx, FrameDescription::state_offset())); 1172 __ push(Operand(ebx, FrameDescription::state_offset()));
1254 } 1173 }
1255 __ push(Operand(ebx, FrameDescription::pc_offset())); 1174 __ push(Operand(ebx, FrameDescription::pc_offset()));
1256 __ push(Operand(ebx, FrameDescription::continuation_offset())); 1175 __ push(Operand(ebx, FrameDescription::continuation_offset()));
1257 1176
(...skipping 24 matching lines...) Expand all
1282 } 1201 }
1283 __ bind(&done); 1202 __ bind(&done);
1284 } 1203 }
1285 1204
1286 #undef __ 1205 #undef __
1287 1206
1288 1207
1289 } } // namespace v8::internal 1208 } } // namespace v8::internal
1290 1209
1291 #endif // V8_TARGET_ARCH_IA32 1210 #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