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/arm/deoptimizer-arm.cc

Issue 11415261: Revert 13117: "Enable stub generation using Hydrogen/Lithium (again)" (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/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 compiled_code_->deoptimization_data()); 225 optimized_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 = compiled_code_->stack_slots() * kPointerSize; 259 unsigned stack_slot_size = optimized_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 compiled_code_->entry() + pc_offset); 351 optimized_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
528 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, 464 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
529 int frame_index) { 465 int frame_index) {
530 Builtins* builtins = isolate_->builtins(); 466 Builtins* builtins = isolate_->builtins();
531 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); 467 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
532 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 468 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
533 unsigned height = iterator->Next(); 469 unsigned height = iterator->Next();
534 unsigned height_in_bytes = height * kPointerSize; 470 unsigned height_in_bytes = height * kPointerSize;
535 if (FLAG_trace_deopt) { 471 if (FLAG_trace_deopt) {
536 PrintF(" translating construct stub => height=%d\n", height_in_bytes); 472 PrintF(" translating construct stub => height=%d\n", height_in_bytes);
537 } 473 }
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 881 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
946 // Set the register values. The values are not important as there are no 882 // Set the register values. The values are not important as there are no
947 // callee saved registers in JavaScript frames, so all registers are 883 // callee saved registers in JavaScript frames, so all registers are
948 // spilled. Registers fp and sp are set to the correct values though. 884 // spilled. Registers fp and sp are set to the correct values though.
949 885
950 for (int i = 0; i < Register::kNumRegisters; i++) { 886 for (int i = 0; i < Register::kNumRegisters; i++) {
951 input_->SetRegister(i, i * 4); 887 input_->SetRegister(i, i * 4);
952 } 888 }
953 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); 889 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
954 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); 890 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
955 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { 891 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) {
956 input_->SetDoubleRegister(i, 0.0); 892 input_->SetDoubleRegister(i, 0.0);
957 } 893 }
958 894
959 // Fill the frame content from the actual data on the frame. 895 // Fill the frame content from the actual data on the frame.
960 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { 896 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
961 input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); 897 input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
962 } 898 }
963 } 899 }
964 900
965 901
966 #define __ masm()-> 902 #define __ masm()->
967 903
968 // This code tries to be close to ia32 code so that any changes can be 904 // This code tries to be close to ia32 code so that any changes can be
969 // easily ported. 905 // easily ported.
970 void Deoptimizer::EntryGenerator::Generate() { 906 void Deoptimizer::EntryGenerator::Generate() {
971 GeneratePrologue(); 907 GeneratePrologue();
972 908
973 Isolate* isolate = masm()->isolate(); 909 Isolate* isolate = masm()->isolate();
974 910
911 CpuFeatures::Scope scope(VFP3);
975 // Save all general purpose registers before messing with them. 912 // Save all general purpose registers before messing with them.
976 const int kNumberOfRegisters = Register::kNumRegisters; 913 const int kNumberOfRegisters = Register::kNumRegisters;
977 914
978 // Everything but pc, lr and ip which will be saved but not restored. 915 // Everything but pc, lr and ip which will be saved but not restored.
979 RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit(); 916 RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit();
980 917
981 const int kDoubleRegsSize = 918 const int kDoubleRegsSize =
982 kDoubleSize * DwVfpRegister::kMaxNumAllocatableRegisters; 919 kDoubleSize * DwVfpRegister::kNumAllocatableRegisters;
983 920
984 if (CpuFeatures::IsSupported(VFP2)) { 921 // Save all VFP registers before messing with them.
985 CpuFeatures::Scope scope(VFP2); 922 DwVfpRegister first = DwVfpRegister::FromAllocationIndex(0);
986 // Save all VFP registers before messing with them. 923 DwVfpRegister last =
987 DwVfpRegister first = DwVfpRegister::FromAllocationIndex(0); 924 DwVfpRegister::FromAllocationIndex(
988 DwVfpRegister last = 925 DwVfpRegister::kNumAllocatableRegisters - 1);
989 DwVfpRegister::FromAllocationIndex( 926 ASSERT(last.code() > first.code());
990 DwVfpRegister::kMaxNumAllocatableRegisters - 1); 927 ASSERT((last.code() - first.code()) ==
991 ASSERT(last.code() > first.code()); 928 (DwVfpRegister::kNumAllocatableRegisters - 1));
992 ASSERT((last.code() - first.code()) ==
993 (DwVfpRegister::kMaxNumAllocatableRegisters - 1));
994 #ifdef DEBUG 929 #ifdef DEBUG
995 int max = DwVfpRegister::kMaxNumAllocatableRegisters - 1; 930 for (int i = 0; i <= (DwVfpRegister::kNumAllocatableRegisters - 1); i++) {
996 for (int i = 0; i <= max; i++) { 931 ASSERT((DwVfpRegister::FromAllocationIndex(i).code() <= last.code()) &&
997 ASSERT((DwVfpRegister::FromAllocationIndex(i).code() <= last.code()) && 932 (DwVfpRegister::FromAllocationIndex(i).code() >= first.code()));
998 (DwVfpRegister::FromAllocationIndex(i).code() >= first.code())); 933 }
999 }
1000 #endif 934 #endif
1001 __ vstm(db_w, sp, first, last); 935 __ vstm(db_w, sp, first, last);
1002 } else {
1003 __ sub(sp, sp, Operand(kDoubleRegsSize));
1004 }
1005 936
1006 // Push all 16 registers (needed to populate FrameDescription::registers_). 937 // Push all 16 registers (needed to populate FrameDescription::registers_).
1007 // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps 938 // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps
1008 // handle this a bit differently. 939 // handle this a bit differently.
1009 __ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit()); 940 __ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit());
1010 941
1011 const int kSavedRegistersAreaSize = 942 const int kSavedRegistersAreaSize =
1012 (kNumberOfRegisters * kPointerSize) + kDoubleRegsSize; 943 (kNumberOfRegisters * kPointerSize) + kDoubleRegsSize;
1013 944
1014 // Get the bailout id from the stack. 945 // Get the bailout id from the stack.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 __ ldr(r1, MemOperand(r0, Deoptimizer::input_offset())); 984 __ ldr(r1, MemOperand(r0, Deoptimizer::input_offset()));
1054 985
1055 // Copy core registers into FrameDescription::registers_[kNumRegisters]. 986 // Copy core registers into FrameDescription::registers_[kNumRegisters].
1056 ASSERT(Register::kNumRegisters == kNumberOfRegisters); 987 ASSERT(Register::kNumRegisters == kNumberOfRegisters);
1057 for (int i = 0; i < kNumberOfRegisters; i++) { 988 for (int i = 0; i < kNumberOfRegisters; i++) {
1058 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 989 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
1059 __ ldr(r2, MemOperand(sp, i * kPointerSize)); 990 __ ldr(r2, MemOperand(sp, i * kPointerSize));
1060 __ str(r2, MemOperand(r1, offset)); 991 __ str(r2, MemOperand(r1, offset));
1061 } 992 }
1062 993
1063 if (CpuFeatures::IsSupported(VFP2)) { 994 // Copy VFP registers to
1064 CpuFeatures::Scope scope(VFP2); 995 // double_registers_[DoubleRegister::kNumAllocatableRegisters]
1065 // Copy VFP registers to 996 int double_regs_offset = FrameDescription::double_registers_offset();
1066 // double_registers_[DoubleRegister::kMaxNumAllocatableRegisters] 997 for (int i = 0; i < DwVfpRegister::kNumAllocatableRegisters; ++i) {
1067 int double_regs_offset = FrameDescription::double_registers_offset(); 998 int dst_offset = i * kDoubleSize + double_regs_offset;
1068 for (int i = 0; i < DwVfpRegister::NumAllocatableRegisters(); ++i) { 999 int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
1069 int dst_offset = i * kDoubleSize + double_regs_offset; 1000 __ vldr(d0, sp, src_offset);
1070 int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize; 1001 __ vstr(d0, r1, dst_offset);
1071 __ vldr(d0, sp, src_offset);
1072 __ vstr(d0, r1, dst_offset);
1073 }
1074 } 1002 }
1075 1003
1076 // Remove the bailout id, eventually return address, and the saved registers 1004 // Remove the bailout id, eventually return address, and the saved registers
1077 // from the stack. 1005 // from the stack.
1078 if (type() == EAGER || type() == OSR) { 1006 if (type() == EAGER || type() == OSR) {
1079 __ add(sp, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); 1007 __ add(sp, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize)));
1080 } else { 1008 } else {
1081 __ add(sp, sp, Operand(kSavedRegistersAreaSize + (2 * kPointerSize))); 1009 __ add(sp, sp, Operand(kSavedRegistersAreaSize + (2 * kPointerSize)));
1082 } 1010 }
1083 1011
1084 // Compute a pointer to the unwinding limit in register r2; that is 1012 // Compute a pointer to the unwinding limit in register r2; that is
1085 // the first stack slot not part of the input frame. 1013 // the first stack slot not part of the input frame.
1086 __ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset())); 1014 __ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset()));
1087 __ add(r2, r2, sp); 1015 __ add(r2, r2, sp);
1088 1016
1089 // Unwind the stack down to - but not including - the unwinding 1017 // Unwind the stack down to - but not including - the unwinding
1090 // limit and copy the contents of the activation frame to the input 1018 // limit and copy the contents of the activation frame to the input
1091 // frame description. 1019 // frame description.
1092 __ add(r3, r1, Operand(FrameDescription::frame_content_offset())); 1020 __ add(r3, r1, Operand(FrameDescription::frame_content_offset()));
1093 Label pop_loop; 1021 Label pop_loop;
1094 Label pop_loop_header;
1095 __ b(&pop_loop_header);
1096 __ bind(&pop_loop); 1022 __ bind(&pop_loop);
1097 __ pop(r4); 1023 __ pop(r4);
1098 __ str(r4, MemOperand(r3, 0)); 1024 __ str(r4, MemOperand(r3, 0));
1099 __ add(r3, r3, Operand(sizeof(uint32_t))); 1025 __ add(r3, r3, Operand(sizeof(uint32_t)));
1100 __ bind(&pop_loop_header);
1101 __ cmp(r2, sp); 1026 __ cmp(r2, sp);
1102 __ b(ne, &pop_loop); 1027 __ b(ne, &pop_loop);
1103 1028
1104 // Compute the output frame in the deoptimizer. 1029 // Compute the output frame in the deoptimizer.
1105 __ push(r0); // Preserve deoptimizer object across call. 1030 __ push(r0); // Preserve deoptimizer object across call.
1106 // r0: deoptimizer object; r1: scratch. 1031 // r0: deoptimizer object; r1: scratch.
1107 __ PrepareCallCFunction(1, r1); 1032 __ PrepareCallCFunction(1, r1);
1108 // Call Deoptimizer::ComputeOutputFrames(). 1033 // Call Deoptimizer::ComputeOutputFrames().
1109 { 1034 {
1110 AllowExternalCallThatCantCauseGC scope(masm()); 1035 AllowExternalCallThatCantCauseGC scope(masm());
1111 __ CallCFunction( 1036 __ CallCFunction(
1112 ExternalReference::compute_output_frames_function(isolate), 1); 1037 ExternalReference::compute_output_frames_function(isolate), 1);
1113 } 1038 }
1114 __ pop(r0); // Restore deoptimizer object (class Deoptimizer). 1039 __ pop(r0); // Restore deoptimizer object (class Deoptimizer).
1115 1040
1116 // Replace the current (input) frame with the output frames. 1041 // Replace the current (input) frame with the output frames.
1117 Label outer_push_loop, inner_push_loop, 1042 Label outer_push_loop, inner_push_loop;
1118 outer_loop_header, inner_loop_header;
1119 // Outer loop state: r0 = current "FrameDescription** output_", 1043 // Outer loop state: r0 = current "FrameDescription** output_",
1120 // r1 = one past the last FrameDescription**. 1044 // r1 = one past the last FrameDescription**.
1121 __ ldr(r1, MemOperand(r0, Deoptimizer::output_count_offset())); 1045 __ ldr(r1, MemOperand(r0, Deoptimizer::output_count_offset()));
1122 __ ldr(r0, MemOperand(r0, Deoptimizer::output_offset())); // r0 is output_. 1046 __ ldr(r0, MemOperand(r0, Deoptimizer::output_offset())); // r0 is output_.
1123 __ add(r1, r0, Operand(r1, LSL, 2)); 1047 __ add(r1, r0, Operand(r1, LSL, 2));
1124 __ jmp(&outer_loop_header);
1125 __ bind(&outer_push_loop); 1048 __ bind(&outer_push_loop);
1126 // Inner loop state: r2 = current FrameDescription*, r3 = loop index. 1049 // Inner loop state: r2 = current FrameDescription*, r3 = loop index.
1127 __ ldr(r2, MemOperand(r0, 0)); // output_[ix] 1050 __ ldr(r2, MemOperand(r0, 0)); // output_[ix]
1128 __ ldr(r3, MemOperand(r2, FrameDescription::frame_size_offset())); 1051 __ ldr(r3, MemOperand(r2, FrameDescription::frame_size_offset()));
1129 __ jmp(&inner_loop_header);
1130 __ bind(&inner_push_loop); 1052 __ bind(&inner_push_loop);
1131 __ sub(r3, r3, Operand(sizeof(uint32_t))); 1053 __ sub(r3, r3, Operand(sizeof(uint32_t)));
1132 __ add(r6, r2, Operand(r3)); 1054 __ add(r6, r2, Operand(r3));
1133 __ ldr(r7, MemOperand(r6, FrameDescription::frame_content_offset())); 1055 __ ldr(r7, MemOperand(r6, FrameDescription::frame_content_offset()));
1134 __ push(r7); 1056 __ push(r7);
1135 __ bind(&inner_loop_header);
1136 __ cmp(r3, Operand(0)); 1057 __ cmp(r3, Operand(0));
1137 __ b(ne, &inner_push_loop); // test for gt? 1058 __ b(ne, &inner_push_loop); // test for gt?
1138 __ add(r0, r0, Operand(kPointerSize)); 1059 __ add(r0, r0, Operand(kPointerSize));
1139 __ bind(&outer_loop_header);
1140 __ cmp(r0, r1); 1060 __ cmp(r0, r1);
1141 __ b(lt, &outer_push_loop); 1061 __ b(lt, &outer_push_loop);
1142 1062
1143 // Push state, pc, and continuation from the last output frame. 1063 // Push state, pc, and continuation from the last output frame.
1144 if (type() != OSR) { 1064 if (type() != OSR) {
1145 __ ldr(r6, MemOperand(r2, FrameDescription::state_offset())); 1065 __ ldr(r6, MemOperand(r2, FrameDescription::state_offset()));
1146 __ push(r6); 1066 __ push(r6);
1147 } 1067 }
1148 1068
1149 __ ldr(r6, MemOperand(r2, FrameDescription::pc_offset())); 1069 __ ldr(r6, MemOperand(r2, FrameDescription::pc_offset()));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 __ push(ip); 1110 __ push(ip);
1191 __ b(&done); 1111 __ b(&done);
1192 ASSERT(masm()->pc_offset() - start == table_entry_size_); 1112 ASSERT(masm()->pc_offset() - start == table_entry_size_);
1193 } 1113 }
1194 __ bind(&done); 1114 __ bind(&done);
1195 } 1115 }
1196 1116
1197 #undef __ 1117 #undef __
1198 1118
1199 } } // namespace v8::internal 1119 } } // 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