OLD | NEW |
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 3012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3023 void MacroAssembler::InvokeCode(Register code, | 3023 void MacroAssembler::InvokeCode(Register code, |
3024 const ParameterCount& expected, | 3024 const ParameterCount& expected, |
3025 const ParameterCount& actual, | 3025 const ParameterCount& actual, |
3026 InvokeFlag flag, | 3026 InvokeFlag flag, |
3027 const CallWrapper& call_wrapper, | 3027 const CallWrapper& call_wrapper, |
3028 CallKind call_kind) { | 3028 CallKind call_kind) { |
3029 // You can't call a function without a valid frame. | 3029 // You can't call a function without a valid frame. |
3030 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3030 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
3031 | 3031 |
3032 Label done; | 3032 Label done; |
| 3033 bool definitely_mismatches = false; |
3033 InvokePrologue(expected, | 3034 InvokePrologue(expected, |
3034 actual, | 3035 actual, |
3035 Handle<Code>::null(), | 3036 Handle<Code>::null(), |
3036 code, | 3037 code, |
3037 &done, | 3038 &done, |
| 3039 &definitely_mismatches, |
3038 flag, | 3040 flag, |
3039 Label::kNear, | 3041 Label::kNear, |
3040 call_wrapper, | 3042 call_wrapper, |
3041 call_kind); | 3043 call_kind); |
3042 if (flag == CALL_FUNCTION) { | 3044 if (!definitely_mismatches) { |
3043 call_wrapper.BeforeCall(CallSize(code)); | 3045 if (flag == CALL_FUNCTION) { |
3044 SetCallKind(rcx, call_kind); | 3046 call_wrapper.BeforeCall(CallSize(code)); |
3045 call(code); | 3047 SetCallKind(rcx, call_kind); |
3046 call_wrapper.AfterCall(); | 3048 call(code); |
3047 } else { | 3049 call_wrapper.AfterCall(); |
3048 ASSERT(flag == JUMP_FUNCTION); | 3050 } else { |
3049 SetCallKind(rcx, call_kind); | 3051 ASSERT(flag == JUMP_FUNCTION); |
3050 jmp(code); | 3052 SetCallKind(rcx, call_kind); |
| 3053 jmp(code); |
| 3054 } |
| 3055 bind(&done); |
3051 } | 3056 } |
3052 bind(&done); | |
3053 } | 3057 } |
3054 | 3058 |
3055 | 3059 |
3056 void MacroAssembler::InvokeCode(Handle<Code> code, | 3060 void MacroAssembler::InvokeCode(Handle<Code> code, |
3057 const ParameterCount& expected, | 3061 const ParameterCount& expected, |
3058 const ParameterCount& actual, | 3062 const ParameterCount& actual, |
3059 RelocInfo::Mode rmode, | 3063 RelocInfo::Mode rmode, |
3060 InvokeFlag flag, | 3064 InvokeFlag flag, |
3061 const CallWrapper& call_wrapper, | 3065 const CallWrapper& call_wrapper, |
3062 CallKind call_kind) { | 3066 CallKind call_kind) { |
3063 // You can't call a function without a valid frame. | 3067 // You can't call a function without a valid frame. |
3064 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3068 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
3065 | 3069 |
3066 Label done; | 3070 Label done; |
| 3071 bool definitely_mismatches = false; |
3067 Register dummy = rax; | 3072 Register dummy = rax; |
3068 InvokePrologue(expected, | 3073 InvokePrologue(expected, |
3069 actual, | 3074 actual, |
3070 code, | 3075 code, |
3071 dummy, | 3076 dummy, |
3072 &done, | 3077 &done, |
| 3078 &definitely_mismatches, |
3073 flag, | 3079 flag, |
3074 Label::kNear, | 3080 Label::kNear, |
3075 call_wrapper, | 3081 call_wrapper, |
3076 call_kind); | 3082 call_kind); |
3077 if (flag == CALL_FUNCTION) { | 3083 if (!definitely_mismatches) { |
3078 call_wrapper.BeforeCall(CallSize(code)); | 3084 if (flag == CALL_FUNCTION) { |
3079 SetCallKind(rcx, call_kind); | 3085 call_wrapper.BeforeCall(CallSize(code)); |
3080 Call(code, rmode); | 3086 SetCallKind(rcx, call_kind); |
3081 call_wrapper.AfterCall(); | 3087 Call(code, rmode); |
3082 } else { | 3088 call_wrapper.AfterCall(); |
3083 ASSERT(flag == JUMP_FUNCTION); | 3089 } else { |
3084 SetCallKind(rcx, call_kind); | 3090 ASSERT(flag == JUMP_FUNCTION); |
3085 Jump(code, rmode); | 3091 SetCallKind(rcx, call_kind); |
| 3092 Jump(code, rmode); |
| 3093 } |
| 3094 bind(&done); |
3086 } | 3095 } |
3087 bind(&done); | |
3088 } | 3096 } |
3089 | 3097 |
3090 | 3098 |
3091 void MacroAssembler::InvokeFunction(Register function, | 3099 void MacroAssembler::InvokeFunction(Register function, |
3092 const ParameterCount& actual, | 3100 const ParameterCount& actual, |
3093 InvokeFlag flag, | 3101 InvokeFlag flag, |
3094 const CallWrapper& call_wrapper, | 3102 const CallWrapper& call_wrapper, |
3095 CallKind call_kind) { | 3103 CallKind call_kind) { |
3096 // You can't call a function without a valid frame. | 3104 // You can't call a function without a valid frame. |
3097 ASSERT(flag == JUMP_FUNCTION || has_frame()); | 3105 ASSERT(flag == JUMP_FUNCTION || has_frame()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3129 ParameterCount expected(function->shared()->formal_parameter_count()); | 3137 ParameterCount expected(function->shared()->formal_parameter_count()); |
3130 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind); | 3138 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind); |
3131 } | 3139 } |
3132 | 3140 |
3133 | 3141 |
3134 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 3142 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
3135 const ParameterCount& actual, | 3143 const ParameterCount& actual, |
3136 Handle<Code> code_constant, | 3144 Handle<Code> code_constant, |
3137 Register code_register, | 3145 Register code_register, |
3138 Label* done, | 3146 Label* done, |
| 3147 bool* definitely_mismatches, |
3139 InvokeFlag flag, | 3148 InvokeFlag flag, |
3140 Label::Distance near_jump, | 3149 Label::Distance near_jump, |
3141 const CallWrapper& call_wrapper, | 3150 const CallWrapper& call_wrapper, |
3142 CallKind call_kind) { | 3151 CallKind call_kind) { |
3143 bool definitely_matches = false; | 3152 bool definitely_matches = false; |
| 3153 *definitely_mismatches = false; |
3144 Label invoke; | 3154 Label invoke; |
3145 if (expected.is_immediate()) { | 3155 if (expected.is_immediate()) { |
3146 ASSERT(actual.is_immediate()); | 3156 ASSERT(actual.is_immediate()); |
3147 if (expected.immediate() == actual.immediate()) { | 3157 if (expected.immediate() == actual.immediate()) { |
3148 definitely_matches = true; | 3158 definitely_matches = true; |
3149 } else { | 3159 } else { |
3150 Set(rax, actual.immediate()); | 3160 Set(rax, actual.immediate()); |
3151 if (expected.immediate() == | 3161 if (expected.immediate() == |
3152 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { | 3162 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { |
3153 // Don't worry about adapting arguments for built-ins that | 3163 // Don't worry about adapting arguments for built-ins that |
3154 // don't want that done. Skip adaption code by making it look | 3164 // don't want that done. Skip adaption code by making it look |
3155 // like we have a match between expected and actual number of | 3165 // like we have a match between expected and actual number of |
3156 // arguments. | 3166 // arguments. |
3157 definitely_matches = true; | 3167 definitely_matches = true; |
3158 } else { | 3168 } else { |
| 3169 *definitely_mismatches = true; |
3159 Set(rbx, expected.immediate()); | 3170 Set(rbx, expected.immediate()); |
3160 } | 3171 } |
3161 } | 3172 } |
3162 } else { | 3173 } else { |
3163 if (actual.is_immediate()) { | 3174 if (actual.is_immediate()) { |
3164 // Expected is in register, actual is immediate. This is the | 3175 // Expected is in register, actual is immediate. This is the |
3165 // case when we invoke function values without going through the | 3176 // case when we invoke function values without going through the |
3166 // IC mechanism. | 3177 // IC mechanism. |
3167 cmpq(expected.reg(), Immediate(actual.immediate())); | 3178 cmpq(expected.reg(), Immediate(actual.immediate())); |
3168 j(equal, &invoke, Label::kNear); | 3179 j(equal, &invoke, Label::kNear); |
(...skipping 16 matching lines...) Expand all Loading... |
3185 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 3196 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
3186 } else if (!code_register.is(rdx)) { | 3197 } else if (!code_register.is(rdx)) { |
3187 movq(rdx, code_register); | 3198 movq(rdx, code_register); |
3188 } | 3199 } |
3189 | 3200 |
3190 if (flag == CALL_FUNCTION) { | 3201 if (flag == CALL_FUNCTION) { |
3191 call_wrapper.BeforeCall(CallSize(adaptor)); | 3202 call_wrapper.BeforeCall(CallSize(adaptor)); |
3192 SetCallKind(rcx, call_kind); | 3203 SetCallKind(rcx, call_kind); |
3193 Call(adaptor, RelocInfo::CODE_TARGET); | 3204 Call(adaptor, RelocInfo::CODE_TARGET); |
3194 call_wrapper.AfterCall(); | 3205 call_wrapper.AfterCall(); |
3195 jmp(done, near_jump); | 3206 if (!*definitely_mismatches) { |
| 3207 jmp(done, near_jump); |
| 3208 } |
3196 } else { | 3209 } else { |
3197 SetCallKind(rcx, call_kind); | 3210 SetCallKind(rcx, call_kind); |
3198 Jump(adaptor, RelocInfo::CODE_TARGET); | 3211 Jump(adaptor, RelocInfo::CODE_TARGET); |
3199 } | 3212 } |
3200 bind(&invoke); | 3213 bind(&invoke); |
3201 } | 3214 } |
3202 } | 3215 } |
3203 | 3216 |
3204 | 3217 |
3205 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 3218 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
(...skipping 1119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4325 | 4338 |
4326 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); | 4339 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); |
4327 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); | 4340 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); |
4328 | 4341 |
4329 bind(&done); | 4342 bind(&done); |
4330 } | 4343 } |
4331 | 4344 |
4332 } } // namespace v8::internal | 4345 } } // namespace v8::internal |
4333 | 4346 |
4334 #endif // V8_TARGET_ARCH_X64 | 4347 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |