| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 chunk()->inlined_closures(); | 959 chunk()->inlined_closures(); |
| 960 | 960 |
| 961 for (int i = 0, length = inlined_closures->length(); i < length; i++) { | 961 for (int i = 0, length = inlined_closures->length(); i < length; i++) { |
| 962 DefineDeoptimizationLiteral(inlined_closures->at(i)); | 962 DefineDeoptimizationLiteral(inlined_closures->at(i)); |
| 963 } | 963 } |
| 964 | 964 |
| 965 inlined_function_count_ = deoptimization_literals_.length(); | 965 inlined_function_count_ = deoptimization_literals_.length(); |
| 966 } | 966 } |
| 967 | 967 |
| 968 | 968 |
| 969 bool LCodeGen::DeoptimizeHeader(LEnvironment* environment) { | 969 Deoptimizer::BailoutType LCodeGen::DeoptimizeHeader( |
| 970 LEnvironment* environment, |
| 971 Deoptimizer::BailoutType* override_bailout_type) { |
| 970 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 972 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); |
| 971 ASSERT(environment->HasBeenRegistered()); | 973 ASSERT(environment->HasBeenRegistered()); |
| 972 ASSERT(info()->IsOptimizing() || info()->IsStub()); | 974 ASSERT(info()->IsOptimizing() || info()->IsStub()); |
| 973 int id = environment->deoptimization_index(); | 975 int id = environment->deoptimization_index(); |
| 974 Deoptimizer::BailoutType bailout_type = info()->IsStub() ? Deoptimizer::LAZY | 976 Deoptimizer::BailoutType bailout_type = |
| 975 : Deoptimizer::EAGER; | 977 info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER; |
| 978 if (override_bailout_type) bailout_type = *override_bailout_type; |
| 976 Address entry = | 979 Address entry = |
| 977 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); | 980 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); |
| 978 | 981 |
| 979 if (entry == NULL) { | 982 if (entry == NULL) { |
| 980 Abort(kBailoutWasNotPrepared); | 983 Abort(kBailoutWasNotPrepared); |
| 981 return false; | 984 return bailout_type; |
| 982 } | 985 } |
| 983 | 986 |
| 984 if (FLAG_deopt_every_n_times != 0 && !info()->IsStub()) { | 987 if (FLAG_deopt_every_n_times != 0 && !info()->IsStub()) { |
| 985 Label not_zero; | 988 Label not_zero; |
| 986 ExternalReference count = ExternalReference::stress_deopt_count(isolate()); | 989 ExternalReference count = ExternalReference::stress_deopt_count(isolate()); |
| 987 | 990 |
| 988 __ Push(x0, x1); | 991 __ Push(x0, x1); |
| 989 __ Mov(x0, Operand(count)); | 992 __ Mov(x0, Operand(count)); |
| 990 __ Ldr(w1, MemOperand(x0)); | 993 __ Ldr(w1, MemOperand(x0)); |
| 991 __ Subs(x1, x1, 1); | 994 __ Subs(x1, x1, 1); |
| 992 __ B(gt, ¬_zero); | 995 __ B(gt, ¬_zero); |
| 993 __ Mov(w1, FLAG_deopt_every_n_times); | 996 __ Mov(w1, FLAG_deopt_every_n_times); |
| 994 __ Str(w1, MemOperand(x0)); | 997 __ Str(w1, MemOperand(x0)); |
| 995 __ Pop(x0, x1); | 998 __ Pop(x0, x1); |
| 996 ASSERT(frame_is_built_); | 999 ASSERT(frame_is_built_); |
| 997 __ Call(entry, RelocInfo::RUNTIME_ENTRY); | 1000 __ Call(entry, RelocInfo::RUNTIME_ENTRY); |
| 998 __ Unreachable(); | 1001 __ Unreachable(); |
| 999 | 1002 |
| 1000 __ Bind(¬_zero); | 1003 __ Bind(¬_zero); |
| 1001 __ Str(w1, MemOperand(x0)); | 1004 __ Str(w1, MemOperand(x0)); |
| 1002 __ Pop(x0, x1); | 1005 __ Pop(x0, x1); |
| 1003 } | 1006 } |
| 1004 | 1007 |
| 1005 return true; | 1008 return bailout_type; |
| 1006 } | 1009 } |
| 1007 | 1010 |
| 1008 | 1011 |
| 1009 void LCodeGen::Deoptimize(LEnvironment* environment, | 1012 void LCodeGen::Deoptimize(LEnvironment* environment, |
| 1010 Deoptimizer::BailoutType bailout_type) { | 1013 Deoptimizer::BailoutType bailout_type) { |
| 1011 if (!DeoptimizeHeader(environment)) return; | |
| 1012 | |
| 1013 ASSERT(environment->HasBeenRegistered()); | 1014 ASSERT(environment->HasBeenRegistered()); |
| 1014 ASSERT(info()->IsOptimizing() || info()->IsStub()); | 1015 ASSERT(info()->IsOptimizing() || info()->IsStub()); |
| 1015 int id = environment->deoptimization_index(); | 1016 int id = environment->deoptimization_index(); |
| 1016 Address entry = | 1017 Address entry = |
| 1017 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); | 1018 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); |
| 1018 | 1019 |
| 1019 if (info()->ShouldTrapOnDeopt()) { | 1020 if (info()->ShouldTrapOnDeopt()) { |
| 1020 __ Debug("trap_on_deopt", __LINE__, BREAK); | 1021 __ Debug("trap_on_deopt", __LINE__, BREAK); |
| 1021 } | 1022 } |
| 1022 | 1023 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1035 bailout_type, | 1036 bailout_type, |
| 1036 !frame_is_built_); | 1037 !frame_is_built_); |
| 1037 deopt_jump_table_.Add(table_entry, zone()); | 1038 deopt_jump_table_.Add(table_entry, zone()); |
| 1038 } | 1039 } |
| 1039 __ B(&deopt_jump_table_.last().label); | 1040 __ B(&deopt_jump_table_.last().label); |
| 1040 } | 1041 } |
| 1041 } | 1042 } |
| 1042 | 1043 |
| 1043 | 1044 |
| 1044 void LCodeGen::Deoptimize(LEnvironment* environment) { | 1045 void LCodeGen::Deoptimize(LEnvironment* environment) { |
| 1045 Deoptimizer::BailoutType bailout_type = info()->IsStub() ? Deoptimizer::LAZY | 1046 Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); |
| 1046 : Deoptimizer::EAGER; | |
| 1047 Deoptimize(environment, bailout_type); | 1047 Deoptimize(environment, bailout_type); |
| 1048 } | 1048 } |
| 1049 | 1049 |
| 1050 | 1050 |
| 1051 void LCodeGen::DeoptimizeIf(Condition cond, LEnvironment* environment) { | 1051 void LCodeGen::DeoptimizeIf(Condition cond, LEnvironment* environment) { |
| 1052 Label dont_deopt; | 1052 Label dont_deopt; |
| 1053 Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); |
| 1053 __ B(InvertCondition(cond), &dont_deopt); | 1054 __ B(InvertCondition(cond), &dont_deopt); |
| 1054 Deoptimize(environment); | 1055 Deoptimize(environment, bailout_type); |
| 1055 __ Bind(&dont_deopt); | 1056 __ Bind(&dont_deopt); |
| 1056 } | 1057 } |
| 1057 | 1058 |
| 1058 | 1059 |
| 1059 void LCodeGen::DeoptimizeIfZero(Register rt, LEnvironment* environment) { | 1060 void LCodeGen::DeoptimizeIfZero(Register rt, LEnvironment* environment) { |
| 1060 Label dont_deopt; | 1061 Label dont_deopt; |
| 1062 Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); |
| 1061 __ Cbnz(rt, &dont_deopt); | 1063 __ Cbnz(rt, &dont_deopt); |
| 1062 Deoptimize(environment); | 1064 Deoptimize(environment, bailout_type); |
| 1063 __ Bind(&dont_deopt); | 1065 __ Bind(&dont_deopt); |
| 1064 } | 1066 } |
| 1065 | 1067 |
| 1066 | 1068 |
| 1067 void LCodeGen::DeoptimizeIfNegative(Register rt, LEnvironment* environment) { | 1069 void LCodeGen::DeoptimizeIfNegative(Register rt, LEnvironment* environment) { |
| 1068 Label dont_deopt; | 1070 Label dont_deopt; |
| 1071 Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); |
| 1069 __ Tbz(rt, rt.Is64Bits() ? kXSignBit : kWSignBit, &dont_deopt); | 1072 __ Tbz(rt, rt.Is64Bits() ? kXSignBit : kWSignBit, &dont_deopt); |
| 1070 Deoptimize(environment); | 1073 Deoptimize(environment, bailout_type); |
| 1071 __ Bind(&dont_deopt); | 1074 __ Bind(&dont_deopt); |
| 1072 } | 1075 } |
| 1073 | 1076 |
| 1074 | 1077 |
| 1075 void LCodeGen::DeoptimizeIfSmi(Register rt, | 1078 void LCodeGen::DeoptimizeIfSmi(Register rt, |
| 1076 LEnvironment* environment) { | 1079 LEnvironment* environment) { |
| 1077 Label dont_deopt; | 1080 Label dont_deopt; |
| 1081 Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); |
| 1078 __ JumpIfNotSmi(rt, &dont_deopt); | 1082 __ JumpIfNotSmi(rt, &dont_deopt); |
| 1079 Deoptimize(environment); | 1083 Deoptimize(environment, bailout_type); |
| 1080 __ Bind(&dont_deopt); | 1084 __ Bind(&dont_deopt); |
| 1081 } | 1085 } |
| 1082 | 1086 |
| 1083 | 1087 |
| 1084 void LCodeGen::DeoptimizeIfNotSmi(Register rt, LEnvironment* environment) { | 1088 void LCodeGen::DeoptimizeIfNotSmi(Register rt, LEnvironment* environment) { |
| 1085 Label dont_deopt; | 1089 Label dont_deopt; |
| 1090 Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); |
| 1086 __ JumpIfSmi(rt, &dont_deopt); | 1091 __ JumpIfSmi(rt, &dont_deopt); |
| 1087 Deoptimize(environment); | 1092 Deoptimize(environment, bailout_type); |
| 1088 __ Bind(&dont_deopt); | 1093 __ Bind(&dont_deopt); |
| 1089 } | 1094 } |
| 1090 | 1095 |
| 1091 | 1096 |
| 1092 void LCodeGen::DeoptimizeIfRoot(Register rt, | 1097 void LCodeGen::DeoptimizeIfRoot(Register rt, |
| 1093 Heap::RootListIndex index, | 1098 Heap::RootListIndex index, |
| 1094 LEnvironment* environment) { | 1099 LEnvironment* environment) { |
| 1095 Label dont_deopt; | 1100 Label dont_deopt; |
| 1101 Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); |
| 1096 __ JumpIfNotRoot(rt, index, &dont_deopt); | 1102 __ JumpIfNotRoot(rt, index, &dont_deopt); |
| 1097 Deoptimize(environment); | 1103 Deoptimize(environment, bailout_type); |
| 1098 __ Bind(&dont_deopt); | 1104 __ Bind(&dont_deopt); |
| 1099 } | 1105 } |
| 1100 | 1106 |
| 1101 | 1107 |
| 1102 void LCodeGen::DeoptimizeIfNotRoot(Register rt, | 1108 void LCodeGen::DeoptimizeIfNotRoot(Register rt, |
| 1103 Heap::RootListIndex index, | 1109 Heap::RootListIndex index, |
| 1104 LEnvironment* environment) { | 1110 LEnvironment* environment) { |
| 1105 Label dont_deopt; | 1111 Label dont_deopt; |
| 1112 Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); |
| 1106 __ JumpIfRoot(rt, index, &dont_deopt); | 1113 __ JumpIfRoot(rt, index, &dont_deopt); |
| 1107 Deoptimize(environment); | 1114 Deoptimize(environment, bailout_type); |
| 1108 __ Bind(&dont_deopt); | 1115 __ Bind(&dont_deopt); |
| 1109 } | 1116 } |
| 1110 | 1117 |
| 1111 | 1118 |
| 1112 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { | 1119 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { |
| 1113 if (!info()->IsStub()) { | 1120 if (!info()->IsStub()) { |
| 1114 // Ensure that we have enough space after the previous lazy-bailout | 1121 // Ensure that we have enough space after the previous lazy-bailout |
| 1115 // instruction for patching the code here. | 1122 // instruction for patching the code here. |
| 1116 intptr_t current_pc = masm()->pc_offset(); | 1123 intptr_t current_pc = masm()->pc_offset(); |
| 1117 | 1124 |
| (...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2548 Deoptimizer::BailoutType type = instr->hydrogen()->type(); | 2555 Deoptimizer::BailoutType type = instr->hydrogen()->type(); |
| 2549 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the | 2556 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the |
| 2550 // needed return address), even though the implementation of LAZY and EAGER is | 2557 // needed return address), even though the implementation of LAZY and EAGER is |
| 2551 // now identical. When LAZY is eventually completely folded into EAGER, remove | 2558 // now identical. When LAZY is eventually completely folded into EAGER, remove |
| 2552 // the special case below. | 2559 // the special case below. |
| 2553 if (info()->IsStub() && (type == Deoptimizer::EAGER)) { | 2560 if (info()->IsStub() && (type == Deoptimizer::EAGER)) { |
| 2554 type = Deoptimizer::LAZY; | 2561 type = Deoptimizer::LAZY; |
| 2555 } | 2562 } |
| 2556 | 2563 |
| 2557 Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); | 2564 Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); |
| 2565 DeoptimizeHeader(instr->environment(), &type); |
| 2558 Deoptimize(instr->environment(), type); | 2566 Deoptimize(instr->environment(), type); |
| 2559 } | 2567 } |
| 2560 | 2568 |
| 2561 | 2569 |
| 2562 void LCodeGen::DoDivI(LDivI* instr) { | 2570 void LCodeGen::DoDivI(LDivI* instr) { |
| 2563 Register dividend = ToRegister32(instr->left()); | 2571 Register dividend = ToRegister32(instr->left()); |
| 2564 Register result = ToRegister32(instr->result()); | 2572 Register result = ToRegister32(instr->result()); |
| 2565 | 2573 |
| 2566 bool has_power_of_2_divisor = instr->hydrogen()->RightIsPowerOf2(); | 2574 bool has_power_of_2_divisor = instr->hydrogen()->RightIsPowerOf2(); |
| 2567 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 2575 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| (...skipping 3161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5729 __ Bind(&out_of_object); | 5737 __ Bind(&out_of_object); |
| 5730 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5738 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 5731 // Index is equal to negated out of object property index plus 1. | 5739 // Index is equal to negated out of object property index plus 1. |
| 5732 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5740 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 5733 __ Ldr(result, FieldMemOperand(result, | 5741 __ Ldr(result, FieldMemOperand(result, |
| 5734 FixedArray::kHeaderSize - kPointerSize)); | 5742 FixedArray::kHeaderSize - kPointerSize)); |
| 5735 __ Bind(&done); | 5743 __ Bind(&done); |
| 5736 } | 5744 } |
| 5737 | 5745 |
| 5738 } } // namespace v8::internal | 5746 } } // namespace v8::internal |
| OLD | NEW |