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

Side by Side Diff: src/arm/macro-assembler-arm.cc

Issue 9178017: Allow call-known-global to be used for call-sites with mismatched number of arguments. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Relax call-constant-function restrictions as well Created 8 years, 11 months 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/macro-assembler-arm.h ('k') | src/arm/stub-cache-arm.cc » ('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 939 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 mov(dst, Operand(Smi::FromInt(0))); 950 mov(dst, Operand(Smi::FromInt(0)));
951 } 951 }
952 } 952 }
953 953
954 954
955 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 955 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
956 const ParameterCount& actual, 956 const ParameterCount& actual,
957 Handle<Code> code_constant, 957 Handle<Code> code_constant,
958 Register code_reg, 958 Register code_reg,
959 Label* done, 959 Label* done,
960 bool* definitely_mismatches,
960 InvokeFlag flag, 961 InvokeFlag flag,
961 const CallWrapper& call_wrapper, 962 const CallWrapper& call_wrapper,
962 CallKind call_kind) { 963 CallKind call_kind) {
963 bool definitely_matches = false; 964 bool definitely_matches = false;
965 *definitely_mismatches = false;
964 Label regular_invoke; 966 Label regular_invoke;
965 967
966 // Check whether the expected and actual arguments count match. If not, 968 // Check whether the expected and actual arguments count match. If not,
967 // setup registers according to contract with ArgumentsAdaptorTrampoline: 969 // setup registers according to contract with ArgumentsAdaptorTrampoline:
968 // r0: actual arguments count 970 // r0: actual arguments count
969 // r1: function (passed through to callee) 971 // r1: function (passed through to callee)
970 // r2: expected arguments count 972 // r2: expected arguments count
971 // r3: callee code entry 973 // r3: callee code entry
972 974
973 // The code below is made a lot easier because the calling code already sets 975 // The code below is made a lot easier because the calling code already sets
(...skipping 10 matching lines...) Expand all
984 } else { 986 } else {
985 mov(r0, Operand(actual.immediate())); 987 mov(r0, Operand(actual.immediate()));
986 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; 988 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
987 if (expected.immediate() == sentinel) { 989 if (expected.immediate() == sentinel) {
988 // Don't worry about adapting arguments for builtins that 990 // Don't worry about adapting arguments for builtins that
989 // don't want that done. Skip adaption code by making it look 991 // don't want that done. Skip adaption code by making it look
990 // like we have a match between expected and actual number of 992 // like we have a match between expected and actual number of
991 // arguments. 993 // arguments.
992 definitely_matches = true; 994 definitely_matches = true;
993 } else { 995 } else {
996 *definitely_mismatches = true;
994 mov(r2, Operand(expected.immediate())); 997 mov(r2, Operand(expected.immediate()));
995 } 998 }
996 } 999 }
997 } else { 1000 } else {
998 if (actual.is_immediate()) { 1001 if (actual.is_immediate()) {
999 cmp(expected.reg(), Operand(actual.immediate())); 1002 cmp(expected.reg(), Operand(actual.immediate()));
1000 b(eq, &regular_invoke); 1003 b(eq, &regular_invoke);
1001 mov(r0, Operand(actual.immediate())); 1004 mov(r0, Operand(actual.immediate()));
1002 } else { 1005 } else {
1003 cmp(expected.reg(), Operand(actual.reg())); 1006 cmp(expected.reg(), Operand(actual.reg()));
1004 b(eq, &regular_invoke); 1007 b(eq, &regular_invoke);
1005 } 1008 }
1006 } 1009 }
1007 1010
1008 if (!definitely_matches) { 1011 if (!definitely_matches) {
1009 if (!code_constant.is_null()) { 1012 if (!code_constant.is_null()) {
1010 mov(r3, Operand(code_constant)); 1013 mov(r3, Operand(code_constant));
1011 add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag)); 1014 add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
1012 } 1015 }
1013 1016
1014 Handle<Code> adaptor = 1017 Handle<Code> adaptor =
1015 isolate()->builtins()->ArgumentsAdaptorTrampoline(); 1018 isolate()->builtins()->ArgumentsAdaptorTrampoline();
1016 if (flag == CALL_FUNCTION) { 1019 if (flag == CALL_FUNCTION) {
1017 call_wrapper.BeforeCall(CallSize(adaptor)); 1020 call_wrapper.BeforeCall(CallSize(adaptor));
1018 SetCallKind(r5, call_kind); 1021 SetCallKind(r5, call_kind);
1019 Call(adaptor); 1022 Call(adaptor);
1020 call_wrapper.AfterCall(); 1023 call_wrapper.AfterCall();
1021 b(done); 1024 if (!*definitely_mismatches) {
1025 b(done);
1026 }
1022 } else { 1027 } else {
1023 SetCallKind(r5, call_kind); 1028 SetCallKind(r5, call_kind);
1024 Jump(adaptor, RelocInfo::CODE_TARGET); 1029 Jump(adaptor, RelocInfo::CODE_TARGET);
1025 } 1030 }
1026 bind(&regular_invoke); 1031 bind(&regular_invoke);
1027 } 1032 }
1028 } 1033 }
1029 1034
1030 1035
1031 void MacroAssembler::InvokeCode(Register code, 1036 void MacroAssembler::InvokeCode(Register code,
1032 const ParameterCount& expected, 1037 const ParameterCount& expected,
1033 const ParameterCount& actual, 1038 const ParameterCount& actual,
1034 InvokeFlag flag, 1039 InvokeFlag flag,
1035 const CallWrapper& call_wrapper, 1040 const CallWrapper& call_wrapper,
1036 CallKind call_kind) { 1041 CallKind call_kind) {
1037 // You can't call a function without a valid frame. 1042 // You can't call a function without a valid frame.
1038 ASSERT(flag == JUMP_FUNCTION || has_frame()); 1043 ASSERT(flag == JUMP_FUNCTION || has_frame());
1039 1044
1040 Label done; 1045 Label done;
1046 bool definitely_mismatches = false;
1047 InvokePrologue(expected, actual, Handle<Code>::null(), code,
1048 &done, &definitely_mismatches, flag,
1049 call_wrapper, call_kind);
1050 if (!definitely_mismatches) {
1051 if (flag == CALL_FUNCTION) {
1052 call_wrapper.BeforeCall(CallSize(code));
1053 SetCallKind(r5, call_kind);
1054 Call(code);
1055 call_wrapper.AfterCall();
1056 } else {
1057 ASSERT(flag == JUMP_FUNCTION);
1058 SetCallKind(r5, call_kind);
1059 Jump(code);
1060 }
1041 1061
1042 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag, 1062 // Continue here if InvokePrologue does handle the invocation due to
1043 call_wrapper, call_kind); 1063 // mismatched parameter counts.
1044 if (flag == CALL_FUNCTION) { 1064 bind(&done);
1045 call_wrapper.BeforeCall(CallSize(code));
1046 SetCallKind(r5, call_kind);
1047 Call(code);
1048 call_wrapper.AfterCall();
1049 } else {
1050 ASSERT(flag == JUMP_FUNCTION);
1051 SetCallKind(r5, call_kind);
1052 Jump(code);
1053 } 1065 }
1054
1055 // Continue here if InvokePrologue does handle the invocation due to
1056 // mismatched parameter counts.
1057 bind(&done);
1058 } 1066 }
1059 1067
1060 1068
1061 void MacroAssembler::InvokeCode(Handle<Code> code, 1069 void MacroAssembler::InvokeCode(Handle<Code> code,
1062 const ParameterCount& expected, 1070 const ParameterCount& expected,
1063 const ParameterCount& actual, 1071 const ParameterCount& actual,
1064 RelocInfo::Mode rmode, 1072 RelocInfo::Mode rmode,
1065 InvokeFlag flag, 1073 InvokeFlag flag,
1066 CallKind call_kind) { 1074 CallKind call_kind) {
1067 // You can't call a function without a valid frame. 1075 // You can't call a function without a valid frame.
1068 ASSERT(flag == JUMP_FUNCTION || has_frame()); 1076 ASSERT(flag == JUMP_FUNCTION || has_frame());
1069 1077
1070 Label done; 1078 Label done;
1079 bool definitely_mismatches = false;
1080 InvokePrologue(expected, actual, code, no_reg,
1081 &done, &definitely_mismatches, flag,
1082 NullCallWrapper(), call_kind);
1083 if (!definitely_mismatches) {
1084 if (flag == CALL_FUNCTION) {
1085 SetCallKind(r5, call_kind);
1086 Call(code, rmode);
1087 } else {
1088 SetCallKind(r5, call_kind);
1089 Jump(code, rmode);
1090 }
1071 1091
1072 InvokePrologue(expected, actual, code, no_reg, &done, flag, 1092 // Continue here if InvokePrologue does handle the invocation due to
1073 NullCallWrapper(), call_kind); 1093 // mismatched parameter counts.
1074 if (flag == CALL_FUNCTION) { 1094 bind(&done);
1075 SetCallKind(r5, call_kind);
1076 Call(code, rmode);
1077 } else {
1078 SetCallKind(r5, call_kind);
1079 Jump(code, rmode);
1080 } 1095 }
1081
1082 // Continue here if InvokePrologue does handle the invocation due to
1083 // mismatched parameter counts.
1084 bind(&done);
1085 } 1096 }
1086 1097
1087 1098
1088 void MacroAssembler::InvokeFunction(Register fun, 1099 void MacroAssembler::InvokeFunction(Register fun,
1089 const ParameterCount& actual, 1100 const ParameterCount& actual,
1090 InvokeFlag flag, 1101 InvokeFlag flag,
1091 const CallWrapper& call_wrapper, 1102 const CallWrapper& call_wrapper,
1092 CallKind call_kind) { 1103 CallKind call_kind) {
1093 // You can't call a function without a valid frame. 1104 // You can't call a function without a valid frame.
1094 ASSERT(flag == JUMP_FUNCTION || has_frame()); 1105 ASSERT(flag == JUMP_FUNCTION || has_frame());
(...skipping 14 matching lines...) Expand all
1109 FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 1120 FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
1110 1121
1111 ParameterCount expected(expected_reg); 1122 ParameterCount expected(expected_reg);
1112 InvokeCode(code_reg, expected, actual, flag, call_wrapper, call_kind); 1123 InvokeCode(code_reg, expected, actual, flag, call_wrapper, call_kind);
1113 } 1124 }
1114 1125
1115 1126
1116 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, 1127 void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
1117 const ParameterCount& actual, 1128 const ParameterCount& actual,
1118 InvokeFlag flag, 1129 InvokeFlag flag,
1130 const CallWrapper& call_wrapper,
1119 CallKind call_kind) { 1131 CallKind call_kind) {
1120 // You can't call a function without a valid frame. 1132 // You can't call a function without a valid frame.
1121 ASSERT(flag == JUMP_FUNCTION || has_frame()); 1133 ASSERT(flag == JUMP_FUNCTION || has_frame());
1122 1134
1123 // Get the function and setup the context. 1135 // Get the function and setup the context.
1124 LoadHeapObject(r1, function); 1136 LoadHeapObject(r1, function);
1125 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 1137 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
1126 1138
1127 ParameterCount expected(function->shared()->formal_parameter_count()); 1139 ParameterCount expected(function->shared()->formal_parameter_count());
1128 // We call indirectly through the code field in the function to 1140 // We call indirectly through the code field in the function to
1129 // allow recompilation to take effect without changing any of the 1141 // allow recompilation to take effect without changing any of the
1130 // call sites. 1142 // call sites.
1131 ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 1143 ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
1132 InvokeCode(r3, expected, actual, flag, NullCallWrapper(), call_kind); 1144 InvokeCode(r3, expected, actual, flag, call_wrapper, call_kind);
1133 } 1145 }
1134 1146
1135 1147
1136 void MacroAssembler::IsObjectJSObjectType(Register heap_object, 1148 void MacroAssembler::IsObjectJSObjectType(Register heap_object,
1137 Register map, 1149 Register map,
1138 Register scratch, 1150 Register scratch,
1139 Label* fail) { 1151 Label* fail) {
1140 ldr(map, FieldMemOperand(heap_object, HeapObject::kMapOffset)); 1152 ldr(map, FieldMemOperand(heap_object, HeapObject::kMapOffset));
1141 IsInstanceJSObjectType(map, scratch, fail); 1153 IsInstanceJSObjectType(map, scratch, fail);
1142 } 1154 }
(...skipping 2523 matching lines...) Expand 10 before | Expand all | Expand 10 after
3666 void CodePatcher::EmitCondition(Condition cond) { 3678 void CodePatcher::EmitCondition(Condition cond) {
3667 Instr instr = Assembler::instr_at(masm_.pc_); 3679 Instr instr = Assembler::instr_at(masm_.pc_);
3668 instr = (instr & ~kCondMask) | cond; 3680 instr = (instr & ~kCondMask) | cond;
3669 masm_.emit(instr); 3681 masm_.emit(instr);
3670 } 3682 }
3671 3683
3672 3684
3673 } } // namespace v8::internal 3685 } } // namespace v8::internal
3674 3686
3675 #endif // V8_TARGET_ARCH_ARM 3687 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/stub-cache-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698