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

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: First pass at pre-VFP2 RA Created 8 years, 1 month 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
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 551 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::DoCompiledStubPseudoFrame(TranslationIterator* iterator,
573 int frame_index) {
574 // Builtins* builtins = isolate_->builtins();
575 // Code::Kind stub_kind = static_cast<Code::Kind>(iterator->Next());
576 FrameDescription* output_frame = new(0) FrameDescription(0, 0);
577 Code* continuation =
578 isolate_->builtins()->builtin(Builtins::kNotifyICMiss);
579 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
580 output_frame->SetContinuation(
581 reinterpret_cast<uint32_t>(continuation->entry()));
582 Handle<Code> miss_ic = isolate_->builtins()->KeyedLoadIC_Miss();
583 output_frame->SetPc(
584 reinterpret_cast<intptr_t>(miss_ic->instruction_start()));
585
586 Code::Kind stub_kind = static_cast<Code::Kind>(iterator->Next());
587 ASSERT(stub_kind == Code::KEYED_LOAD_IC);
588 USE(stub_kind);
589
590 Translation::Opcode opcode =
591 static_cast<Translation::Opcode>(iterator->Next());
592 ASSERT(opcode == Translation::REGISTER);
593 USE(opcode);
594 int input_reg = iterator->Next();
595 intptr_t input_value = input_->GetRegister(input_reg);
596 output_frame->SetRegister(edx.code(), input_value);
597
598 int32_t next = iterator->Next();
599 opcode = static_cast<Translation::Opcode>(next);
600 ASSERT(opcode == Translation::REGISTER);
601 input_reg = iterator->Next();
602 input_value = input_->GetRegister(input_reg);
603 output_frame->SetRegister(ecx.code(), input_value);
604
605 Address frame_ptr =
606 reinterpret_cast<Address>(input_->GetRegister(ebp.code()));
607 Address context_ptr_raw = frame_ptr + StandardFrameConstants::kContextOffset;
608 Context** context_ptr =
609 reinterpret_cast<Context**>(context_ptr_raw);
610 output_frame->SetRegister(esi.code(),
611 reinterpret_cast<intptr_t>(*context_ptr));
612 output_frame->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame_ptr));
613
614 ASSERT(frame_index == 0);
615 output_[frame_index] = output_frame;
616 }
617
618
572 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, 619 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
573 int frame_index) { 620 int frame_index) {
574 Builtins* builtins = isolate_->builtins(); 621 Builtins* builtins = isolate_->builtins();
575 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); 622 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
576 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 623 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
577 unsigned height = iterator->Next(); 624 unsigned height = iterator->Next();
578 unsigned height_in_bytes = height * kPointerSize; 625 unsigned height_in_bytes = height * kPointerSize;
579 if (FLAG_trace_deopt) { 626 if (FLAG_trace_deopt) {
580 PrintF(" translating construct stub => height=%d\n", height_in_bytes); 627 PrintF(" translating construct stub => height=%d\n", height_in_bytes);
581 } 628 }
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 1037 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
991 // Set the register values. The values are not important as there are no 1038 // Set the register values. The values are not important as there are no
992 // callee saved registers in JavaScript frames, so all registers are 1039 // callee saved registers in JavaScript frames, so all registers are
993 // spilled. Registers ebp and esp are set to the correct values though. 1040 // spilled. Registers ebp and esp are set to the correct values though.
994 1041
995 for (int i = 0; i < Register::kNumRegisters; i++) { 1042 for (int i = 0; i < Register::kNumRegisters; i++) {
996 input_->SetRegister(i, i * 4); 1043 input_->SetRegister(i, i * 4);
997 } 1044 }
998 input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp())); 1045 input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp()));
999 input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp())); 1046 input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp()));
1000 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) { 1047 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
1001 input_->SetDoubleRegister(i, 0.0); 1048 input_->SetDoubleRegister(i, 0.0);
1002 } 1049 }
1003 1050
1004 // Fill the frame content from the actual data on the frame. 1051 // Fill the frame content from the actual data on the frame.
1005 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { 1052 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
1006 input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); 1053 input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
1007 } 1054 }
1008 } 1055 }
1009 1056
1010 1057
1011 #define __ masm()-> 1058 #define __ masm()->
1012 1059
1013 void Deoptimizer::EntryGenerator::Generate() { 1060 void Deoptimizer::EntryGenerator::Generate() {
1014 GeneratePrologue(); 1061 GeneratePrologue();
1015 CpuFeatures::Scope scope(SSE2);
1016 1062
1017 Isolate* isolate = masm()->isolate(); 1063 Isolate* isolate = masm()->isolate();
1018 1064
1019 // Save all general purpose registers before messing with them. 1065 // Save all general purpose registers before messing with them.
1020 const int kNumberOfRegisters = Register::kNumRegisters; 1066 const int kNumberOfRegisters = Register::kNumRegisters;
1021 1067
1022 const int kDoubleRegsSize = kDoubleSize * 1068 const int kDoubleRegsSize = kDoubleSize *
1023 XMMRegister::kNumAllocatableRegisters; 1069 XMMRegister::kNumAllocatableRegisters;
1024 __ sub(esp, Immediate(kDoubleRegsSize)); 1070 __ sub(esp, Immediate(kDoubleRegsSize));
1025 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) { 1071 if (CpuFeatures::IsSupported(SSE2)) {
1026 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i); 1072 CpuFeatures::Scope scope(SSE2);
1027 int offset = i * kDoubleSize; 1073 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
1028 __ movdbl(Operand(esp, offset), xmm_reg); 1074 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
1075 int offset = i * kDoubleSize;
1076 __ movdbl(Operand(esp, offset), xmm_reg);
1077 }
1029 } 1078 }
1030 1079
1031 __ pushad(); 1080 __ pushad();
1032 1081
1033 const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize + 1082 const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize +
1034 kDoubleRegsSize; 1083 kDoubleRegsSize;
1035 1084
1036 // Get the bailout id from the stack. 1085 // Get the bailout id from the stack.
1037 __ mov(ebx, Operand(esp, kSavedRegistersAreaSize)); 1086 __ mov(ebx, Operand(esp, kSavedRegistersAreaSize));
1038 1087
(...skipping 27 matching lines...) Expand all
1066 // Preserve deoptimizer object in register eax and get the input 1115 // Preserve deoptimizer object in register eax and get the input
1067 // frame descriptor pointer. 1116 // frame descriptor pointer.
1068 __ mov(ebx, Operand(eax, Deoptimizer::input_offset())); 1117 __ mov(ebx, Operand(eax, Deoptimizer::input_offset()));
1069 1118
1070 // Fill in the input registers. 1119 // Fill in the input registers.
1071 for (int i = kNumberOfRegisters - 1; i >= 0; i--) { 1120 for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
1072 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 1121 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
1073 __ pop(Operand(ebx, offset)); 1122 __ pop(Operand(ebx, offset));
1074 } 1123 }
1075 1124
1076 // Fill in the double input registers.
1077 int double_regs_offset = FrameDescription::double_registers_offset(); 1125 int double_regs_offset = FrameDescription::double_registers_offset();
1078 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) { 1126 if (CpuFeatures::IsSupported(SSE2)) {
1079 int dst_offset = i * kDoubleSize + double_regs_offset; 1127 CpuFeatures::Scope scope(SSE2);
1080 int src_offset = i * kDoubleSize; 1128 // Fill in the double input registers.
1081 __ movdbl(xmm0, Operand(esp, src_offset)); 1129 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
1082 __ movdbl(Operand(ebx, dst_offset), xmm0); 1130 int dst_offset = i * kDoubleSize + double_regs_offset;
1131 int src_offset = i * kDoubleSize;
1132 __ movdbl(xmm0, Operand(esp, src_offset));
1133 __ movdbl(Operand(ebx, dst_offset), xmm0);
1134 }
1083 } 1135 }
1136 __ fninit();
1084 1137
1085 // Remove the bailout id and the double registers from the stack. 1138 // Remove the bailout id and the double registers from the stack.
1086 if (type() == EAGER) { 1139 if (type() == EAGER) {
1087 __ add(esp, Immediate(kDoubleRegsSize + kPointerSize)); 1140 __ add(esp, Immediate(kDoubleRegsSize + kPointerSize));
1088 } else { 1141 } else {
1089 __ add(esp, Immediate(kDoubleRegsSize + 2 * kPointerSize)); 1142 __ add(esp, Immediate(kDoubleRegsSize + 2 * kPointerSize));
1090 } 1143 }
1091 1144
1092 // Compute a pointer to the unwinding limit in register ecx; that is 1145 // Compute a pointer to the unwinding limit in register ecx; that is
1093 // the first stack slot not part of the input frame. 1146 // the first stack slot not part of the input frame.
1094 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset())); 1147 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset()));
1095 __ add(ecx, esp); 1148 __ add(ecx, esp);
1096 1149
1097 // Unwind the stack down to - but not including - the unwinding 1150 // Unwind the stack down to - but not including - the unwinding
1098 // limit and copy the contents of the activation frame to the input 1151 // limit and copy the contents of the activation frame to the input
1099 // frame description. 1152 // frame description.
1100 __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset())); 1153 __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset()));
1154 Label pop_loop_header;
1155 __ jmp(&pop_loop_header);
1101 Label pop_loop; 1156 Label pop_loop;
1102 __ bind(&pop_loop); 1157 __ bind(&pop_loop);
1103 __ pop(Operand(edx, 0)); 1158 __ pop(Operand(edx, 0));
1104 __ add(edx, Immediate(sizeof(uint32_t))); 1159 __ add(edx, Immediate(sizeof(uint32_t)));
1160 __ bind(&pop_loop_header);
1105 __ cmp(ecx, esp); 1161 __ cmp(ecx, esp);
1106 __ j(not_equal, &pop_loop); 1162 __ j(not_equal, &pop_loop);
1107 1163
1108 // Compute the output frame in the deoptimizer. 1164 // Compute the output frame in the deoptimizer.
1109 __ push(eax); 1165 __ push(eax);
1110 __ PrepareCallCFunction(1, ebx); 1166 __ PrepareCallCFunction(1, ebx);
1111 __ mov(Operand(esp, 0 * kPointerSize), eax); 1167 __ mov(Operand(esp, 0 * kPointerSize), eax);
1112 { 1168 {
1113 AllowExternalCallThatCantCauseGC scope(masm()); 1169 AllowExternalCallThatCantCauseGC scope(masm());
1114 __ CallCFunction( 1170 __ CallCFunction(
(...skipping 17 matching lines...) Expand all
1132 // If frame needs dynamic alignment push padding. 1188 // If frame needs dynamic alignment push padding.
1133 Label no_padding; 1189 Label no_padding;
1134 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), 1190 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
1135 Immediate(0)); 1191 Immediate(0));
1136 __ j(equal, &no_padding); 1192 __ j(equal, &no_padding);
1137 __ push(Immediate(kAlignmentZapValue)); 1193 __ push(Immediate(kAlignmentZapValue));
1138 __ bind(&no_padding); 1194 __ bind(&no_padding);
1139 } 1195 }
1140 1196
1141 // Replace the current frame with the output frames. 1197 // Replace the current frame with the output frames.
1142 Label outer_push_loop, inner_push_loop; 1198 Label outer_push_loop, inner_push_loop,
1199 outer_loop_header, inner_loop_header;
1143 // Outer loop state: eax = current FrameDescription**, edx = one past the 1200 // Outer loop state: eax = current FrameDescription**, edx = one past the
1144 // last FrameDescription**. 1201 // last FrameDescription**.
1145 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); 1202 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset()));
1146 __ mov(eax, Operand(eax, Deoptimizer::output_offset())); 1203 __ mov(eax, Operand(eax, Deoptimizer::output_offset()));
1147 __ lea(edx, Operand(eax, edx, times_4, 0)); 1204 __ lea(edx, Operand(eax, edx, times_4, 0));
1205 __ jmp(&outer_loop_header);
1148 __ bind(&outer_push_loop); 1206 __ bind(&outer_push_loop);
1149 // Inner loop state: ebx = current FrameDescription*, ecx = loop index. 1207 // Inner loop state: ebx = current FrameDescription*, ecx = loop index.
1150 __ mov(ebx, Operand(eax, 0)); 1208 __ mov(ebx, Operand(eax, 0));
1151 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset())); 1209 __ mov(ecx, Operand(ebx, FrameDescription::frame_size_offset()));
1210 __ jmp(&inner_loop_header);
1152 __ bind(&inner_push_loop); 1211 __ bind(&inner_push_loop);
1153 __ sub(ecx, Immediate(sizeof(uint32_t))); 1212 __ sub(ecx, Immediate(sizeof(uint32_t)));
1154 __ push(Operand(ebx, ecx, times_1, FrameDescription::frame_content_offset())); 1213 __ push(Operand(ebx, ecx, times_1, FrameDescription::frame_content_offset()));
1214 __ bind(&inner_loop_header);
1155 __ test(ecx, ecx); 1215 __ test(ecx, ecx);
1156 __ j(not_zero, &inner_push_loop); 1216 __ j(not_zero, &inner_push_loop);
1157 __ add(eax, Immediate(kPointerSize)); 1217 __ add(eax, Immediate(kPointerSize));
1218 __ bind(&outer_loop_header);
1158 __ cmp(eax, edx); 1219 __ cmp(eax, edx);
1159 __ j(below, &outer_push_loop); 1220 __ j(below, &outer_push_loop);
1160 1221
1161 // In case of OSR, we have to restore the XMM registers. 1222 // In case of OSR, we have to restore the XMM registers.
1162 if (type() == OSR) { 1223 if (type() == OSR) {
1163 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) { 1224 if (CpuFeatures::IsSupported(SSE2)) {
1164 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i); 1225 CpuFeatures::Scope scope(SSE2);
1165 int src_offset = i * kDoubleSize + double_regs_offset; 1226 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
1166 __ movdbl(xmm_reg, Operand(ebx, src_offset)); 1227 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
1228 int src_offset = i * kDoubleSize + double_regs_offset;
1229 __ movdbl(xmm_reg, Operand(ebx, src_offset));
1230 }
1167 } 1231 }
1168 } 1232 }
1169 1233
1170 // Push state, pc, and continuation from the last output frame. 1234 // Push state, pc, and continuation from the last output frame.
1171 if (type() != OSR) { 1235 if (type() != OSR) {
1172 __ push(Operand(ebx, FrameDescription::state_offset())); 1236 __ push(Operand(ebx, FrameDescription::state_offset()));
1173 } 1237 }
1174 __ push(Operand(ebx, FrameDescription::pc_offset())); 1238 __ push(Operand(ebx, FrameDescription::pc_offset()));
1175 __ push(Operand(ebx, FrameDescription::continuation_offset())); 1239 __ push(Operand(ebx, FrameDescription::continuation_offset()));
1176 1240
(...skipping 24 matching lines...) Expand all
1201 } 1265 }
1202 __ bind(&done); 1266 __ bind(&done);
1203 } 1267 }
1204 1268
1205 #undef __ 1269 #undef __
1206 1270
1207 1271
1208 } } // namespace v8::internal 1272 } } // namespace v8::internal
1209 1273
1210 #endif // V8_TARGET_ARCH_IA32 1274 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698