OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 __ movq(num_args.reg(), Immediate(arg_count)); | 1039 __ movq(num_args.reg(), Immediate(arg_count)); |
1040 | 1040 |
1041 function.Unuse(); | 1041 function.Unuse(); |
1042 num_args.Unuse(); | 1042 num_args.Unuse(); |
1043 return RawCallCodeObject(ic, RelocInfo::CONSTRUCT_CALL); | 1043 return RawCallCodeObject(ic, RelocInfo::CONSTRUCT_CALL); |
1044 } | 1044 } |
1045 | 1045 |
1046 | 1046 |
1047 Result VirtualFrame::CallStoreIC() { | 1047 Result VirtualFrame::CallStoreIC() { |
1048 // Name, value, and receiver are on top of the frame. The IC | 1048 // Name, value, and receiver are on top of the frame. The IC |
1049 // expects name in rcx, value in rax, and receiver on the stack. It | 1049 // expects name in rcx, value in rax, and receiver in edx. |
1050 // does not drop the receiver. | |
1051 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1050 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1052 Result name = Pop(); | 1051 Result name = Pop(); |
1053 Result value = Pop(); | 1052 Result value = Pop(); |
1054 PrepareForCall(1, 0); // One stack arg, not callee-dropped. | 1053 Result receiver = Pop(); |
| 1054 PrepareForCall(0, 0); |
1055 | 1055 |
1056 if (value.is_register() && value.reg().is(rcx)) { | 1056 // Optimized for case in which name is a constant value. |
1057 if (name.is_register() && name.reg().is(rax)) { | 1057 if (name.is_register() && (name.reg().is(rdx) || name.reg().is(rax))) { |
| 1058 if (!is_used(rcx)) { |
| 1059 name.ToRegister(rcx); |
| 1060 } else if (!is_used(rbx)) { |
| 1061 name.ToRegister(rbx); |
| 1062 } else { |
| 1063 ASSERT(!is_used(rdi)); // Only three results are live, so rdi is free. |
| 1064 name.ToRegister(rdi); |
| 1065 } |
| 1066 } |
| 1067 // Now name is not in edx or eax, so we can fix them, then move name to ecx. |
| 1068 if (value.is_register() && value.reg().is(rdx)) { |
| 1069 if (receiver.is_register() && receiver.reg().is(rax)) { |
1058 // Wrong registers. | 1070 // Wrong registers. |
1059 __ xchg(rax, rcx); | 1071 __ xchg(rax, rdx); |
1060 } else { | 1072 } else { |
1061 // Register rax is free for value, which frees rcx for name. | 1073 // Register rax is free for value, which frees rcx for receiver. |
1062 value.ToRegister(rax); | 1074 value.ToRegister(rax); |
1063 name.ToRegister(rcx); | 1075 receiver.ToRegister(rdx); |
1064 } | 1076 } |
1065 } else { | 1077 } else { |
1066 // Register rcx is free for name, which guarantees rax is free for | 1078 // Register rcx is free for receiver, which guarantees rax is free for |
1067 // value. | 1079 // value. |
1068 name.ToRegister(rcx); | 1080 receiver.ToRegister(rdx); |
1069 value.ToRegister(rax); | 1081 value.ToRegister(rax); |
1070 } | 1082 } |
1071 | 1083 // Receiver and value are in the right place, so rcx is free for name. |
| 1084 name.ToRegister(rcx); |
1072 name.Unuse(); | 1085 name.Unuse(); |
1073 value.Unuse(); | 1086 value.Unuse(); |
| 1087 receiver.Unuse(); |
1074 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); | 1088 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); |
1075 } | 1089 } |
1076 | 1090 |
1077 | 1091 |
1078 void VirtualFrame::PushTryHandler(HandlerType type) { | 1092 void VirtualFrame::PushTryHandler(HandlerType type) { |
1079 ASSERT(cgen()->HasValidEntryRegisters()); | 1093 ASSERT(cgen()->HasValidEntryRegisters()); |
1080 // Grow the expression stack by handler size less one (the return | 1094 // Grow the expression stack by handler size less one (the return |
1081 // address is already pushed by a call instruction). | 1095 // address is already pushed by a call instruction). |
1082 Adjust(kHandlerSize - 1); | 1096 Adjust(kHandlerSize - 1); |
1083 __ PushTryHandler(IN_JAVASCRIPT, type); | 1097 __ PushTryHandler(IN_JAVASCRIPT, type); |
1084 } | 1098 } |
1085 | 1099 |
1086 | 1100 |
1087 #undef __ | 1101 #undef __ |
1088 | 1102 |
1089 } } // namespace v8::internal | 1103 } } // namespace v8::internal |
OLD | NEW |