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

Side by Side Diff: src/arm/deoptimizer-arm.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/arm/codegen-arm.cc ('k') | src/arm/lithium-arm.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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 if (value == 1) return i; 215 if (value == 1) return i;
216 } 216 }
217 } 217 }
218 UNREACHABLE(); 218 UNREACHABLE();
219 return -1; 219 return -1;
220 } 220 }
221 221
222 222
223 void Deoptimizer::DoComputeOsrOutputFrame() { 223 void Deoptimizer::DoComputeOsrOutputFrame() {
224 DeoptimizationInputData* data = DeoptimizationInputData::cast( 224 DeoptimizationInputData* data = DeoptimizationInputData::cast(
225 optimized_code_->deoptimization_data()); 225 compiled_code_->deoptimization_data());
226 unsigned ast_id = data->OsrAstId()->value(); 226 unsigned ast_id = data->OsrAstId()->value();
227 227
228 int bailout_id = LookupBailoutId(data, BailoutId(ast_id)); 228 int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
229 unsigned translation_index = data->TranslationIndex(bailout_id)->value(); 229 unsigned translation_index = data->TranslationIndex(bailout_id)->value();
230 ByteArray* translations = data->TranslationByteArray(); 230 ByteArray* translations = data->TranslationByteArray();
231 231
232 TranslationIterator iterator(translations, translation_index); 232 TranslationIterator iterator(translations, translation_index);
233 Translation::Opcode opcode = 233 Translation::Opcode opcode =
234 static_cast<Translation::Opcode>(iterator.Next()); 234 static_cast<Translation::Opcode>(iterator.Next());
235 ASSERT(Translation::BEGIN == opcode); 235 ASSERT(Translation::BEGIN == opcode);
(...skipping 13 matching lines...) Expand all
249 USE(closure_id); 249 USE(closure_id);
250 ASSERT_EQ(Translation::kSelfLiteralId, closure_id); 250 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
251 unsigned height = iterator.Next(); 251 unsigned height = iterator.Next();
252 unsigned height_in_bytes = height * kPointerSize; 252 unsigned height_in_bytes = height * kPointerSize;
253 USE(height_in_bytes); 253 USE(height_in_bytes);
254 254
255 unsigned fixed_size = ComputeFixedSize(function_); 255 unsigned fixed_size = ComputeFixedSize(function_);
256 unsigned input_frame_size = input_->GetFrameSize(); 256 unsigned input_frame_size = input_->GetFrameSize();
257 ASSERT(fixed_size + height_in_bytes == input_frame_size); 257 ASSERT(fixed_size + height_in_bytes == input_frame_size);
258 258
259 unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize; 259 unsigned stack_slot_size = compiled_code_->stack_slots() * kPointerSize;
260 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value(); 260 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
261 unsigned outgoing_size = outgoing_height * kPointerSize; 261 unsigned outgoing_size = outgoing_height * kPointerSize;
262 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size; 262 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
263 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call. 263 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call.
264 264
265 if (FLAG_trace_osr) { 265 if (FLAG_trace_osr) {
266 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ", 266 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ",
267 reinterpret_cast<intptr_t>(function_)); 267 reinterpret_cast<intptr_t>(function_));
268 function_->PrintName(); 268 function_->PrintName();
269 PrintF(" => node=%u, frame=%d->%d]\n", 269 PrintF(" => node=%u, frame=%d->%d]\n",
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 delete output_[0]; 341 delete output_[0];
342 output_[0] = input_; 342 output_[0] = input_;
343 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); 343 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_));
344 } else { 344 } else {
345 // Set up the frame pointer and the context pointer. 345 // Set up the frame pointer and the context pointer.
346 output_[0]->SetRegister(fp.code(), input_->GetRegister(fp.code())); 346 output_[0]->SetRegister(fp.code(), input_->GetRegister(fp.code()));
347 output_[0]->SetRegister(cp.code(), input_->GetRegister(cp.code())); 347 output_[0]->SetRegister(cp.code(), input_->GetRegister(cp.code()));
348 348
349 unsigned pc_offset = data->OsrPcOffset()->value(); 349 unsigned pc_offset = data->OsrPcOffset()->value();
350 uint32_t pc = reinterpret_cast<uint32_t>( 350 uint32_t pc = reinterpret_cast<uint32_t>(
351 optimized_code_->entry() + pc_offset); 351 compiled_code_->entry() + pc_offset);
352 output_[0]->SetPc(pc); 352 output_[0]->SetPc(pc);
353 } 353 }
354 Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR); 354 Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR);
355 output_[0]->SetContinuation( 355 output_[0]->SetContinuation(
356 reinterpret_cast<uint32_t>(continuation->entry())); 356 reinterpret_cast<uint32_t>(continuation->entry()));
357 357
358 if (FLAG_trace_osr) { 358 if (FLAG_trace_osr) {
359 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", 359 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
360 ok ? "finished" : "aborted", 360 ok ? "finished" : "aborted",
361 reinterpret_cast<intptr_t>(function_)); 361 reinterpret_cast<intptr_t>(function_));
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 Builtins* builtins = isolate_->builtins(); 454 Builtins* builtins = isolate_->builtins();
455 Code* adaptor_trampoline = 455 Code* adaptor_trampoline =
456 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); 456 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
457 uint32_t pc = reinterpret_cast<uint32_t>( 457 uint32_t pc = reinterpret_cast<uint32_t>(
458 adaptor_trampoline->instruction_start() + 458 adaptor_trampoline->instruction_start() +
459 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); 459 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
460 output_frame->SetPc(pc); 460 output_frame->SetPc(pc);
461 } 461 }
462 462
463 463
464 void Deoptimizer::DoCompiledStubFrame(TranslationIterator* iterator,
465 int frame_index) {
466 //
467 // FROM TO <-fp
468 // | .... | | .... |
469 // +-------------------------+ +-------------------------+
470 // | JSFunction continuation | | JSFunction continuation |
471 // +-------------------------+ +-------------------------+<-sp
472 // | | saved frame (fp) |
473 // | +=========================+<-fp
474 // | | JSFunction context |
475 // v +-------------------------+
476 // | COMPILED_STUB marker | fp = saved frame
477 // +-------------------------+ f8 = JSFunction context
478 // | |
479 // | ... |
480 // | |
481 // +-------------------------+<-sp
482 //
483 //
484 int output_frame_size = 1 * kPointerSize;
485 FrameDescription* output_frame =
486 new(output_frame_size) FrameDescription(output_frame_size, 0);
487 Code* notify_miss =
488 isolate_->builtins()->builtin(Builtins::kNotifyICMiss);
489 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
490 output_frame->SetContinuation(
491 reinterpret_cast<intptr_t>(notify_miss->entry()));
492
493 ASSERT(compiled_code_->kind() == Code::COMPILED_STUB);
494 int major_key = compiled_code_->major_key();
495 CodeStubInterfaceDescriptor* descriptor =
496 isolate_->code_stub_interface_descriptors()[major_key];
497 Handle<Code> miss_ic(descriptor->deoptimization_handler);
498 output_frame->SetPc(reinterpret_cast<intptr_t>(miss_ic->instruction_start()));
499 unsigned input_frame_size = input_->GetFrameSize();
500 intptr_t value = input_->GetFrameSlot(input_frame_size - kPointerSize);
501 output_frame->SetFrameSlot(0, value);
502 value = input_->GetFrameSlot(input_frame_size - 2 * kPointerSize);
503 output_frame->SetRegister(fp.code(), value);
504 output_frame->SetFp(value);
505 value = input_->GetFrameSlot(input_frame_size - 3 * kPointerSize);
506 output_frame->SetRegister(cp.code(), value);
507
508 Translation::Opcode opcode =
509 static_cast<Translation::Opcode>(iterator->Next());
510 ASSERT(opcode == Translation::REGISTER);
511 USE(opcode);
512 int input_reg = iterator->Next();
513 intptr_t input_value = input_->GetRegister(input_reg);
514 output_frame->SetRegister(r1.code(), input_value);
515
516 int32_t next = iterator->Next();
517 opcode = static_cast<Translation::Opcode>(next);
518 ASSERT(opcode == Translation::REGISTER);
519 input_reg = iterator->Next();
520 input_value = input_->GetRegister(input_reg);
521 output_frame->SetRegister(r0.code(), input_value);
522
523 ASSERT(frame_index == 0);
524 output_[frame_index] = output_frame;
525 }
526
527
464 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, 528 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
465 int frame_index) { 529 int frame_index) {
466 Builtins* builtins = isolate_->builtins(); 530 Builtins* builtins = isolate_->builtins();
467 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); 531 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
468 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 532 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
469 unsigned height = iterator->Next(); 533 unsigned height = iterator->Next();
470 unsigned height_in_bytes = height * kPointerSize; 534 unsigned height_in_bytes = height * kPointerSize;
471 if (FLAG_trace_deopt) { 535 if (FLAG_trace_deopt) {
472 PrintF(" translating construct stub => height=%d\n", height_in_bytes); 536 PrintF(" translating construct stub => height=%d\n", height_in_bytes);
473 } 537 }
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 945 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
882 // Set the register values. The values are not important as there are no 946 // Set the register values. The values are not important as there are no
883 // callee saved registers in JavaScript frames, so all registers are 947 // callee saved registers in JavaScript frames, so all registers are
884 // spilled. Registers fp and sp are set to the correct values though. 948 // spilled. Registers fp and sp are set to the correct values though.
885 949
886 for (int i = 0; i < Register::kNumRegisters; i++) { 950 for (int i = 0; i < Register::kNumRegisters; i++) {
887 input_->SetRegister(i, i * 4); 951 input_->SetRegister(i, i * 4);
888 } 952 }
889 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); 953 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
890 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); 954 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
891 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) { 955 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
892 input_->SetDoubleRegister(i, 0.0); 956 input_->SetDoubleRegister(i, 0.0);
893 } 957 }
894 958
895 // Fill the frame content from the actual data on the frame. 959 // Fill the frame content from the actual data on the frame.
896 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { 960 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
897 input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); 961 input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
898 } 962 }
899 } 963 }
900 964
901 965
902 #define __ masm()-> 966 #define __ masm()->
903 967
904 // This code tries to be close to ia32 code so that any changes can be 968 // This code tries to be close to ia32 code so that any changes can be
905 // easily ported. 969 // easily ported.
906 void Deoptimizer::EntryGenerator::Generate() { 970 void Deoptimizer::EntryGenerator::Generate() {
907 GeneratePrologue(); 971 GeneratePrologue();
908 972
909 Isolate* isolate = masm()->isolate(); 973 Isolate* isolate = masm()->isolate();
910 974
911 CpuFeatures::Scope scope(VFP3);
912 // Save all general purpose registers before messing with them. 975 // Save all general purpose registers before messing with them.
913 const int kNumberOfRegisters = Register::kNumRegisters; 976 const int kNumberOfRegisters = Register::kNumRegisters;
914 977
915 // Everything but pc, lr and ip which will be saved but not restored. 978 // Everything but pc, lr and ip which will be saved but not restored.
916 RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit(); 979 RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit();
917 980
918 const int kDoubleRegsSize = 981 const int kDoubleRegsSize =
919 kDoubleSize * DwVfpRegister::kNumAllocatableRegisters; 982 kDoubleSize * DwVfpRegister::kMaxNumAllocatableRegisters;
920 983
921 // Save all VFP registers before messing with them. 984 if (CpuFeatures::IsSupported(VFP2)) {
922 DwVfpRegister first = DwVfpRegister::FromAllocationIndex(0); 985 CpuFeatures::Scope scope(VFP2);
923 DwVfpRegister last = 986 // Save all VFP registers before messing with them.
924 DwVfpRegister::FromAllocationIndex( 987 DwVfpRegister first = DwVfpRegister::FromAllocationIndex(0);
925 DwVfpRegister::kNumAllocatableRegisters - 1); 988 DwVfpRegister last =
926 ASSERT(last.code() > first.code()); 989 DwVfpRegister::FromAllocationIndex(
927 ASSERT((last.code() - first.code()) == 990 DwVfpRegister::kMaxNumAllocatableRegisters - 1);
928 (DwVfpRegister::kNumAllocatableRegisters - 1)); 991 ASSERT(last.code() > first.code());
992 ASSERT((last.code() - first.code()) ==
993 (DwVfpRegister::kMaxNumAllocatableRegisters - 1));
929 #ifdef DEBUG 994 #ifdef DEBUG
930 for (int i = 0; i <= (DwVfpRegister::kNumAllocatableRegisters - 1); i++) { 995 int max = DwVfpRegister::kMaxNumAllocatableRegisters - 1;
931 ASSERT((DwVfpRegister::FromAllocationIndex(i).code() <= last.code()) && 996 for (int i = 0; i <= max; i++) {
932 (DwVfpRegister::FromAllocationIndex(i).code() >= first.code())); 997 ASSERT((DwVfpRegister::FromAllocationIndex(i).code() <= last.code()) &&
998 (DwVfpRegister::FromAllocationIndex(i).code() >= first.code()));
999 }
1000 #endif
1001 __ vstm(db_w, sp, first, last);
1002 } else {
1003 __ sub(sp, sp, Operand(kDoubleRegsSize));
933 } 1004 }
934 #endif
935 __ vstm(db_w, sp, first, last);
936 1005
937 // Push all 16 registers (needed to populate FrameDescription::registers_). 1006 // Push all 16 registers (needed to populate FrameDescription::registers_).
938 // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps 1007 // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps
939 // handle this a bit differently. 1008 // handle this a bit differently.
940 __ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit()); 1009 __ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit());
941 1010
942 const int kSavedRegistersAreaSize = 1011 const int kSavedRegistersAreaSize =
943 (kNumberOfRegisters * kPointerSize) + kDoubleRegsSize; 1012 (kNumberOfRegisters * kPointerSize) + kDoubleRegsSize;
944 1013
945 // Get the bailout id from the stack. 1014 // Get the bailout id from the stack.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 __ ldr(r1, MemOperand(r0, Deoptimizer::input_offset())); 1053 __ ldr(r1, MemOperand(r0, Deoptimizer::input_offset()));
985 1054
986 // Copy core registers into FrameDescription::registers_[kNumRegisters]. 1055 // Copy core registers into FrameDescription::registers_[kNumRegisters].
987 ASSERT(Register::kNumRegisters == kNumberOfRegisters); 1056 ASSERT(Register::kNumRegisters == kNumberOfRegisters);
988 for (int i = 0; i < kNumberOfRegisters; i++) { 1057 for (int i = 0; i < kNumberOfRegisters; i++) {
989 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 1058 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
990 __ ldr(r2, MemOperand(sp, i * kPointerSize)); 1059 __ ldr(r2, MemOperand(sp, i * kPointerSize));
991 __ str(r2, MemOperand(r1, offset)); 1060 __ str(r2, MemOperand(r1, offset));
992 } 1061 }
993 1062
994 // Copy VFP registers to 1063 if (CpuFeatures::IsSupported(VFP2)) {
995 // double_registers_[DoubleRegister::kNumAllocatableRegisters] 1064 CpuFeatures::Scope scope(VFP2);
996 int double_regs_offset = FrameDescription::double_registers_offset(); 1065 // Copy VFP registers to
997 for (int i = 0; i < DwVfpRegister::kNumAllocatableRegisters; ++i) { 1066 // double_registers_[DoubleRegister::kMaxNumAllocatableRegisters]
998 int dst_offset = i * kDoubleSize + double_regs_offset; 1067 int double_regs_offset = FrameDescription::double_registers_offset();
999 int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize; 1068 for (int i = 0; i < DwVfpRegister::NumAllocatableRegisters(); ++i) {
1000 __ vldr(d0, sp, src_offset); 1069 int dst_offset = i * kDoubleSize + double_regs_offset;
1001 __ vstr(d0, r1, dst_offset); 1070 int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
1071 __ vldr(d0, sp, src_offset);
1072 __ vstr(d0, r1, dst_offset);
1073 }
1002 } 1074 }
1003 1075
1004 // Remove the bailout id, eventually return address, and the saved registers 1076 // Remove the bailout id, eventually return address, and the saved registers
1005 // from the stack. 1077 // from the stack.
1006 if (type() == EAGER || type() == OSR) { 1078 if (type() == EAGER || type() == OSR) {
1007 __ add(sp, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); 1079 __ add(sp, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize)));
1008 } else { 1080 } else {
1009 __ add(sp, sp, Operand(kSavedRegistersAreaSize + (2 * kPointerSize))); 1081 __ add(sp, sp, Operand(kSavedRegistersAreaSize + (2 * kPointerSize)));
1010 } 1082 }
1011 1083
1012 // Compute a pointer to the unwinding limit in register r2; that is 1084 // Compute a pointer to the unwinding limit in register r2; that is
1013 // the first stack slot not part of the input frame. 1085 // the first stack slot not part of the input frame.
1014 __ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset())); 1086 __ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset()));
1015 __ add(r2, r2, sp); 1087 __ add(r2, r2, sp);
1016 1088
1017 // Unwind the stack down to - but not including - the unwinding 1089 // Unwind the stack down to - but not including - the unwinding
1018 // limit and copy the contents of the activation frame to the input 1090 // limit and copy the contents of the activation frame to the input
1019 // frame description. 1091 // frame description.
1020 __ add(r3, r1, Operand(FrameDescription::frame_content_offset())); 1092 __ add(r3, r1, Operand(FrameDescription::frame_content_offset()));
1021 Label pop_loop; 1093 Label pop_loop;
1094 Label pop_loop_header;
1095 __ b(&pop_loop_header);
1022 __ bind(&pop_loop); 1096 __ bind(&pop_loop);
1023 __ pop(r4); 1097 __ pop(r4);
1024 __ str(r4, MemOperand(r3, 0)); 1098 __ str(r4, MemOperand(r3, 0));
1025 __ add(r3, r3, Operand(sizeof(uint32_t))); 1099 __ add(r3, r3, Operand(sizeof(uint32_t)));
1100 __ bind(&pop_loop_header);
1026 __ cmp(r2, sp); 1101 __ cmp(r2, sp);
1027 __ b(ne, &pop_loop); 1102 __ b(ne, &pop_loop);
1028 1103
1029 // Compute the output frame in the deoptimizer. 1104 // Compute the output frame in the deoptimizer.
1030 __ push(r0); // Preserve deoptimizer object across call. 1105 __ push(r0); // Preserve deoptimizer object across call.
1031 // r0: deoptimizer object; r1: scratch. 1106 // r0: deoptimizer object; r1: scratch.
1032 __ PrepareCallCFunction(1, r1); 1107 __ PrepareCallCFunction(1, r1);
1033 // Call Deoptimizer::ComputeOutputFrames(). 1108 // Call Deoptimizer::ComputeOutputFrames().
1034 { 1109 {
1035 AllowExternalCallThatCantCauseGC scope(masm()); 1110 AllowExternalCallThatCantCauseGC scope(masm());
1036 __ CallCFunction( 1111 __ CallCFunction(
1037 ExternalReference::compute_output_frames_function(isolate), 1); 1112 ExternalReference::compute_output_frames_function(isolate), 1);
1038 } 1113 }
1039 __ pop(r0); // Restore deoptimizer object (class Deoptimizer). 1114 __ pop(r0); // Restore deoptimizer object (class Deoptimizer).
1040 1115
1041 // Replace the current (input) frame with the output frames. 1116 // Replace the current (input) frame with the output frames.
1042 Label outer_push_loop, inner_push_loop; 1117 Label outer_push_loop, inner_push_loop,
1118 outer_loop_header, inner_loop_header;
1043 // Outer loop state: r0 = current "FrameDescription** output_", 1119 // Outer loop state: r0 = current "FrameDescription** output_",
1044 // r1 = one past the last FrameDescription**. 1120 // r1 = one past the last FrameDescription**.
1045 __ ldr(r1, MemOperand(r0, Deoptimizer::output_count_offset())); 1121 __ ldr(r1, MemOperand(r0, Deoptimizer::output_count_offset()));
1046 __ ldr(r0, MemOperand(r0, Deoptimizer::output_offset())); // r0 is output_. 1122 __ ldr(r0, MemOperand(r0, Deoptimizer::output_offset())); // r0 is output_.
1047 __ add(r1, r0, Operand(r1, LSL, 2)); 1123 __ add(r1, r0, Operand(r1, LSL, 2));
1124 __ jmp(&outer_loop_header);
1048 __ bind(&outer_push_loop); 1125 __ bind(&outer_push_loop);
1049 // Inner loop state: r2 = current FrameDescription*, r3 = loop index. 1126 // Inner loop state: r2 = current FrameDescription*, r3 = loop index.
1050 __ ldr(r2, MemOperand(r0, 0)); // output_[ix] 1127 __ ldr(r2, MemOperand(r0, 0)); // output_[ix]
1051 __ ldr(r3, MemOperand(r2, FrameDescription::frame_size_offset())); 1128 __ ldr(r3, MemOperand(r2, FrameDescription::frame_size_offset()));
1129 __ jmp(&inner_loop_header);
1052 __ bind(&inner_push_loop); 1130 __ bind(&inner_push_loop);
1053 __ sub(r3, r3, Operand(sizeof(uint32_t))); 1131 __ sub(r3, r3, Operand(sizeof(uint32_t)));
1054 __ add(r6, r2, Operand(r3)); 1132 __ add(r6, r2, Operand(r3));
1055 __ ldr(r7, MemOperand(r6, FrameDescription::frame_content_offset())); 1133 __ ldr(r7, MemOperand(r6, FrameDescription::frame_content_offset()));
1056 __ push(r7); 1134 __ push(r7);
1135 __ bind(&inner_loop_header);
1057 __ cmp(r3, Operand(0)); 1136 __ cmp(r3, Operand(0));
1058 __ b(ne, &inner_push_loop); // test for gt? 1137 __ b(ne, &inner_push_loop); // test for gt?
1059 __ add(r0, r0, Operand(kPointerSize)); 1138 __ add(r0, r0, Operand(kPointerSize));
1139 __ bind(&outer_loop_header);
1060 __ cmp(r0, r1); 1140 __ cmp(r0, r1);
1061 __ b(lt, &outer_push_loop); 1141 __ b(lt, &outer_push_loop);
1062 1142
1063 // Push state, pc, and continuation from the last output frame. 1143 // Push state, pc, and continuation from the last output frame.
1064 if (type() != OSR) { 1144 if (type() != OSR) {
1065 __ ldr(r6, MemOperand(r2, FrameDescription::state_offset())); 1145 __ ldr(r6, MemOperand(r2, FrameDescription::state_offset()));
1066 __ push(r6); 1146 __ push(r6);
1067 } 1147 }
1068 1148
1069 __ ldr(r6, MemOperand(r2, FrameDescription::pc_offset())); 1149 __ ldr(r6, MemOperand(r2, FrameDescription::pc_offset()));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 __ push(ip); 1190 __ push(ip);
1111 __ b(&done); 1191 __ b(&done);
1112 ASSERT(masm()->pc_offset() - start == table_entry_size_); 1192 ASSERT(masm()->pc_offset() - start == table_entry_size_);
1113 } 1193 }
1114 __ bind(&done); 1194 __ bind(&done);
1115 } 1195 }
1116 1196
1117 #undef __ 1197 #undef __
1118 1198
1119 } } // namespace v8::internal 1199 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698