| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 // Patch the receiver on the stack with the global proxy. | 962 // Patch the receiver on the stack with the global proxy. |
| 963 if (object->IsGlobalObject()) { | 963 if (object->IsGlobalObject()) { |
| 964 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 964 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
| 965 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 965 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
| 966 } | 966 } |
| 967 | 967 |
| 968 // Setup the context (function already in edi). | 968 // Setup the context (function already in edi). |
| 969 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 969 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
| 970 | 970 |
| 971 // Jump to the cached code (tail call). | 971 // Jump to the cached code (tail call). |
| 972 __ IncrementCounter(&Counters::call_global_inline, 1); | 972 __ IncrementCounter(&COUNTER(call_global_inline), 1); |
| 973 ASSERT(function->is_compiled()); | 973 ASSERT(function->is_compiled()); |
| 974 Handle<Code> code(function->code()); | 974 Handle<Code> code(function->code()); |
| 975 ParameterCount expected(function->shared()->formal_parameter_count()); | 975 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 976 __ InvokeCode(code, expected, arguments(), | 976 __ InvokeCode(code, expected, arguments(), |
| 977 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 977 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
| 978 | 978 |
| 979 // Handle call cache miss. | 979 // Handle call cache miss. |
| 980 __ bind(&miss); | 980 __ bind(&miss); |
| 981 __ IncrementCounter(&Counters::call_global_inline_miss, 1); | 981 __ IncrementCounter(&COUNTER(call_global_inline_miss), 1); |
| 982 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 982 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
| 983 __ Jump(ic, RelocInfo::CODE_TARGET); | 983 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 984 | 984 |
| 985 // Return the generated code. | 985 // Return the generated code. |
| 986 return GetCode(NORMAL, name); | 986 return GetCode(NORMAL, name); |
| 987 } | 987 } |
| 988 | 988 |
| 989 | 989 |
| 990 Object* LoadStubCompiler::CompileLoadCallback(JSObject* object, | 990 Object* LoadStubCompiler::CompileLoadCallback(JSObject* object, |
| 991 JSObject* holder, | 991 JSObject* holder, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 | 1116 |
| 1117 // Check for deleted property if property can actually be deleted. | 1117 // Check for deleted property if property can actually be deleted. |
| 1118 if (!is_dont_delete) { | 1118 if (!is_dont_delete) { |
| 1119 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); | 1119 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); |
| 1120 __ j(equal, &miss); | 1120 __ j(equal, &miss); |
| 1121 } else if (FLAG_debug_code) { | 1121 } else if (FLAG_debug_code) { |
| 1122 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); | 1122 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); |
| 1123 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 1123 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
| 1124 } | 1124 } |
| 1125 | 1125 |
| 1126 __ IncrementCounter(&Counters::named_load_global_inline, 1); | 1126 __ IncrementCounter(&COUNTER(named_load_global_inline), 1); |
| 1127 __ ret(0); | 1127 __ ret(0); |
| 1128 | 1128 |
| 1129 __ bind(&miss); | 1129 __ bind(&miss); |
| 1130 __ IncrementCounter(&Counters::named_load_global_inline_miss, 1); | 1130 __ IncrementCounter(&COUNTER(named_load_global_inline_miss), 1); |
| 1131 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1131 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 1132 | 1132 |
| 1133 // Return the generated code. | 1133 // Return the generated code. |
| 1134 return GetCode(NORMAL, name); | 1134 return GetCode(NORMAL, name); |
| 1135 } | 1135 } |
| 1136 | 1136 |
| 1137 | 1137 |
| 1138 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, | 1138 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, |
| 1139 JSObject* receiver, | 1139 JSObject* receiver, |
| 1140 JSObject* holder, | 1140 JSObject* holder, |
| 1141 AccessorInfo* callback) { | 1141 AccessorInfo* callback) { |
| 1142 // ----------- S t a t e ------------- | 1142 // ----------- S t a t e ------------- |
| 1143 // -- rsp[0] : return address | 1143 // -- rsp[0] : return address |
| 1144 // -- rsp[8] : name | 1144 // -- rsp[8] : name |
| 1145 // -- rsp[16] : receiver | 1145 // -- rsp[16] : receiver |
| 1146 // ----------------------------------- | 1146 // ----------------------------------- |
| 1147 Label miss; | 1147 Label miss; |
| 1148 | 1148 |
| 1149 __ movq(rax, Operand(rsp, kPointerSize)); | 1149 __ movq(rax, Operand(rsp, kPointerSize)); |
| 1150 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); | 1150 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); |
| 1151 __ IncrementCounter(&Counters::keyed_load_callback, 1); | 1151 __ IncrementCounter(&COUNTER(keyed_load_callback), 1); |
| 1152 | 1152 |
| 1153 // Check that the name has not changed. | 1153 // Check that the name has not changed. |
| 1154 __ Cmp(rax, Handle<String>(name)); | 1154 __ Cmp(rax, Handle<String>(name)); |
| 1155 __ j(not_equal, &miss); | 1155 __ j(not_equal, &miss); |
| 1156 | 1156 |
| 1157 GenerateLoadCallback(receiver, holder, rcx, rax, rbx, rdx, | 1157 GenerateLoadCallback(receiver, holder, rcx, rax, rbx, rdx, |
| 1158 callback, name, &miss); | 1158 callback, name, &miss); |
| 1159 __ bind(&miss); | 1159 __ bind(&miss); |
| 1160 __ DecrementCounter(&Counters::keyed_load_callback, 1); | 1160 __ DecrementCounter(&COUNTER(keyed_load_callback), 1); |
| 1161 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1161 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1162 | 1162 |
| 1163 // Return the generated code. | 1163 // Return the generated code. |
| 1164 return GetCode(CALLBACKS, name); | 1164 return GetCode(CALLBACKS, name); |
| 1165 } | 1165 } |
| 1166 | 1166 |
| 1167 | 1167 |
| 1168 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 1168 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { |
| 1169 // ----------- S t a t e ------------- | 1169 // ----------- S t a t e ------------- |
| 1170 // -- rsp[0] : return address | 1170 // -- rsp[0] : return address |
| 1171 // -- rsp[8] : name | 1171 // -- rsp[8] : name |
| 1172 // -- rsp[16] : receiver | 1172 // -- rsp[16] : receiver |
| 1173 // ----------------------------------- | 1173 // ----------------------------------- |
| 1174 Label miss; | 1174 Label miss; |
| 1175 | 1175 |
| 1176 __ movq(rax, Operand(rsp, kPointerSize)); | 1176 __ movq(rax, Operand(rsp, kPointerSize)); |
| 1177 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); | 1177 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); |
| 1178 __ IncrementCounter(&Counters::keyed_load_array_length, 1); | 1178 __ IncrementCounter(&COUNTER(keyed_load_array_length), 1); |
| 1179 | 1179 |
| 1180 // Check that the name has not changed. | 1180 // Check that the name has not changed. |
| 1181 __ Cmp(rax, Handle<String>(name)); | 1181 __ Cmp(rax, Handle<String>(name)); |
| 1182 __ j(not_equal, &miss); | 1182 __ j(not_equal, &miss); |
| 1183 | 1183 |
| 1184 GenerateLoadArrayLength(masm(), rcx, rdx, &miss); | 1184 GenerateLoadArrayLength(masm(), rcx, rdx, &miss); |
| 1185 __ bind(&miss); | 1185 __ bind(&miss); |
| 1186 __ DecrementCounter(&Counters::keyed_load_array_length, 1); | 1186 __ DecrementCounter(&COUNTER(keyed_load_array_length), 1); |
| 1187 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1187 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1188 | 1188 |
| 1189 // Return the generated code. | 1189 // Return the generated code. |
| 1190 return GetCode(CALLBACKS, name); | 1190 return GetCode(CALLBACKS, name); |
| 1191 } | 1191 } |
| 1192 | 1192 |
| 1193 | 1193 |
| 1194 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 1194 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, |
| 1195 JSObject* receiver, | 1195 JSObject* receiver, |
| 1196 JSObject* holder, | 1196 JSObject* holder, |
| 1197 Object* value) { | 1197 Object* value) { |
| 1198 // ----------- S t a t e ------------- | 1198 // ----------- S t a t e ------------- |
| 1199 // -- rsp[0] : return address | 1199 // -- rsp[0] : return address |
| 1200 // -- rsp[8] : name | 1200 // -- rsp[8] : name |
| 1201 // -- rsp[16] : receiver | 1201 // -- rsp[16] : receiver |
| 1202 // ----------------------------------- | 1202 // ----------------------------------- |
| 1203 Label miss; | 1203 Label miss; |
| 1204 | 1204 |
| 1205 __ movq(rax, Operand(rsp, kPointerSize)); | 1205 __ movq(rax, Operand(rsp, kPointerSize)); |
| 1206 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); | 1206 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); |
| 1207 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); | 1207 __ IncrementCounter(&COUNTER(keyed_load_constant_function), 1); |
| 1208 | 1208 |
| 1209 // Check that the name has not changed. | 1209 // Check that the name has not changed. |
| 1210 __ Cmp(rax, Handle<String>(name)); | 1210 __ Cmp(rax, Handle<String>(name)); |
| 1211 __ j(not_equal, &miss); | 1211 __ j(not_equal, &miss); |
| 1212 | 1212 |
| 1213 GenerateLoadConstant(receiver, holder, rcx, rbx, rdx, | 1213 GenerateLoadConstant(receiver, holder, rcx, rbx, rdx, |
| 1214 value, name, &miss); | 1214 value, name, &miss); |
| 1215 __ bind(&miss); | 1215 __ bind(&miss); |
| 1216 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); | 1216 __ DecrementCounter(&COUNTER(keyed_load_constant_function), 1); |
| 1217 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1217 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1218 | 1218 |
| 1219 // Return the generated code. | 1219 // Return the generated code. |
| 1220 return GetCode(CONSTANT_FUNCTION, name); | 1220 return GetCode(CONSTANT_FUNCTION, name); |
| 1221 } | 1221 } |
| 1222 | 1222 |
| 1223 | 1223 |
| 1224 Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 1224 Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
| 1225 // ----------- S t a t e ------------- | 1225 // ----------- S t a t e ------------- |
| 1226 // -- rsp[0] : return address | 1226 // -- rsp[0] : return address |
| 1227 // -- rsp[8] : name | 1227 // -- rsp[8] : name |
| 1228 // -- rsp[16] : receiver | 1228 // -- rsp[16] : receiver |
| 1229 // ----------------------------------- | 1229 // ----------------------------------- |
| 1230 Label miss; | 1230 Label miss; |
| 1231 | 1231 |
| 1232 __ movq(rax, Operand(rsp, kPointerSize)); | 1232 __ movq(rax, Operand(rsp, kPointerSize)); |
| 1233 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); | 1233 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); |
| 1234 __ IncrementCounter(&Counters::keyed_load_function_prototype, 1); | 1234 __ IncrementCounter(&COUNTER(keyed_load_function_prototype), 1); |
| 1235 | 1235 |
| 1236 // Check that the name has not changed. | 1236 // Check that the name has not changed. |
| 1237 __ Cmp(rax, Handle<String>(name)); | 1237 __ Cmp(rax, Handle<String>(name)); |
| 1238 __ j(not_equal, &miss); | 1238 __ j(not_equal, &miss); |
| 1239 | 1239 |
| 1240 GenerateLoadFunctionPrototype(masm(), rcx, rdx, rbx, &miss); | 1240 GenerateLoadFunctionPrototype(masm(), rcx, rdx, rbx, &miss); |
| 1241 __ bind(&miss); | 1241 __ bind(&miss); |
| 1242 __ DecrementCounter(&Counters::keyed_load_function_prototype, 1); | 1242 __ DecrementCounter(&COUNTER(keyed_load_function_prototype), 1); |
| 1243 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1243 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1244 | 1244 |
| 1245 // Return the generated code. | 1245 // Return the generated code. |
| 1246 return GetCode(CALLBACKS, name); | 1246 return GetCode(CALLBACKS, name); |
| 1247 } | 1247 } |
| 1248 | 1248 |
| 1249 | 1249 |
| 1250 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 1250 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
| 1251 JSObject* holder, | 1251 JSObject* holder, |
| 1252 String* name) { | 1252 String* name) { |
| 1253 // ----------- S t a t e ------------- | 1253 // ----------- S t a t e ------------- |
| 1254 // -- rsp[0] : return address | 1254 // -- rsp[0] : return address |
| 1255 // -- rsp[8] : name | 1255 // -- rsp[8] : name |
| 1256 // -- rsp[16] : receiver | 1256 // -- rsp[16] : receiver |
| 1257 // ----------------------------------- | 1257 // ----------------------------------- |
| 1258 Label miss; | 1258 Label miss; |
| 1259 | 1259 |
| 1260 __ movq(rax, Operand(rsp, kPointerSize)); | 1260 __ movq(rax, Operand(rsp, kPointerSize)); |
| 1261 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); | 1261 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); |
| 1262 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); | 1262 __ IncrementCounter(&COUNTER(keyed_load_interceptor), 1); |
| 1263 | 1263 |
| 1264 // Check that the name has not changed. | 1264 // Check that the name has not changed. |
| 1265 __ Cmp(rax, Handle<String>(name)); | 1265 __ Cmp(rax, Handle<String>(name)); |
| 1266 __ j(not_equal, &miss); | 1266 __ j(not_equal, &miss); |
| 1267 | 1267 |
| 1268 LookupResult lookup; | 1268 LookupResult lookup; |
| 1269 LookupPostInterceptor(holder, name, &lookup); | 1269 LookupPostInterceptor(holder, name, &lookup); |
| 1270 GenerateLoadInterceptor(receiver, | 1270 GenerateLoadInterceptor(receiver, |
| 1271 holder, | 1271 holder, |
| 1272 &lookup, | 1272 &lookup, |
| 1273 rcx, | 1273 rcx, |
| 1274 rax, | 1274 rax, |
| 1275 rdx, | 1275 rdx, |
| 1276 rbx, | 1276 rbx, |
| 1277 name, | 1277 name, |
| 1278 &miss); | 1278 &miss); |
| 1279 __ bind(&miss); | 1279 __ bind(&miss); |
| 1280 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); | 1280 __ DecrementCounter(&COUNTER(keyed_load_interceptor), 1); |
| 1281 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1281 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1282 | 1282 |
| 1283 // Return the generated code. | 1283 // Return the generated code. |
| 1284 return GetCode(INTERCEPTOR, name); | 1284 return GetCode(INTERCEPTOR, name); |
| 1285 } | 1285 } |
| 1286 | 1286 |
| 1287 | 1287 |
| 1288 Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 1288 Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { |
| 1289 // ----------- S t a t e ------------- | 1289 // ----------- S t a t e ------------- |
| 1290 // -- rsp[0] : return address | 1290 // -- rsp[0] : return address |
| 1291 // -- rsp[8] : name | 1291 // -- rsp[8] : name |
| 1292 // -- rsp[16] : receiver | 1292 // -- rsp[16] : receiver |
| 1293 // ----------------------------------- | 1293 // ----------------------------------- |
| 1294 Label miss; | 1294 Label miss; |
| 1295 | 1295 |
| 1296 __ movq(rax, Operand(rsp, kPointerSize)); | 1296 __ movq(rax, Operand(rsp, kPointerSize)); |
| 1297 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); | 1297 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); |
| 1298 __ IncrementCounter(&Counters::keyed_load_string_length, 1); | 1298 __ IncrementCounter(&COUNTER(keyed_load_string_length), 1); |
| 1299 | 1299 |
| 1300 // Check that the name has not changed. | 1300 // Check that the name has not changed. |
| 1301 __ Cmp(rax, Handle<String>(name)); | 1301 __ Cmp(rax, Handle<String>(name)); |
| 1302 __ j(not_equal, &miss); | 1302 __ j(not_equal, &miss); |
| 1303 | 1303 |
| 1304 GenerateLoadStringLength(masm(), rcx, rdx, &miss); | 1304 GenerateLoadStringLength(masm(), rcx, rdx, &miss); |
| 1305 __ bind(&miss); | 1305 __ bind(&miss); |
| 1306 __ DecrementCounter(&Counters::keyed_load_string_length, 1); | 1306 __ DecrementCounter(&COUNTER(keyed_load_string_length), 1); |
| 1307 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1307 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1308 | 1308 |
| 1309 // Return the generated code. | 1309 // Return the generated code. |
| 1310 return GetCode(CALLBACKS, name); | 1310 return GetCode(CALLBACKS, name); |
| 1311 } | 1311 } |
| 1312 | 1312 |
| 1313 | 1313 |
| 1314 Object* StoreStubCompiler::CompileStoreCallback(JSObject* object, | 1314 Object* StoreStubCompiler::CompileStoreCallback(JSObject* object, |
| 1315 AccessorInfo* callback, | 1315 AccessorInfo* callback, |
| 1316 String* name) { | 1316 String* name) { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1467 __ movq(rbx, Operand(rsp, kPointerSize)); | 1467 __ movq(rbx, Operand(rsp, kPointerSize)); |
| 1468 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), | 1468 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), |
| 1469 Handle<Map>(object->map())); | 1469 Handle<Map>(object->map())); |
| 1470 __ j(not_equal, &miss); | 1470 __ j(not_equal, &miss); |
| 1471 | 1471 |
| 1472 // Store the value in the cell. | 1472 // Store the value in the cell. |
| 1473 __ Move(rcx, Handle<JSGlobalPropertyCell>(cell)); | 1473 __ Move(rcx, Handle<JSGlobalPropertyCell>(cell)); |
| 1474 __ movq(FieldOperand(rcx, JSGlobalPropertyCell::kValueOffset), rax); | 1474 __ movq(FieldOperand(rcx, JSGlobalPropertyCell::kValueOffset), rax); |
| 1475 | 1475 |
| 1476 // Return the value (register rax). | 1476 // Return the value (register rax). |
| 1477 __ IncrementCounter(&Counters::named_store_global_inline, 1); | 1477 __ IncrementCounter(&COUNTER(named_store_global_inline), 1); |
| 1478 __ ret(0); | 1478 __ ret(0); |
| 1479 | 1479 |
| 1480 // Handle store cache miss. | 1480 // Handle store cache miss. |
| 1481 __ bind(&miss); | 1481 __ bind(&miss); |
| 1482 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1); | 1482 __ IncrementCounter(&COUNTER(named_store_global_inline_miss), 1); |
| 1483 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 1483 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); |
| 1484 __ Jump(ic, RelocInfo::CODE_TARGET); | 1484 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 1485 | 1485 |
| 1486 // Return the generated code. | 1486 // Return the generated code. |
| 1487 return GetCode(NORMAL, name); | 1487 return GetCode(NORMAL, name); |
| 1488 } | 1488 } |
| 1489 | 1489 |
| 1490 | 1490 |
| 1491 Object* KeyedLoadStubCompiler::CompileLoadField(String* name, | 1491 Object* KeyedLoadStubCompiler::CompileLoadField(String* name, |
| 1492 JSObject* receiver, | 1492 JSObject* receiver, |
| 1493 JSObject* holder, | 1493 JSObject* holder, |
| 1494 int index) { | 1494 int index) { |
| 1495 // ----------- S t a t e ------------- | 1495 // ----------- S t a t e ------------- |
| 1496 // -- rsp[0] : return address | 1496 // -- rsp[0] : return address |
| 1497 // -- rsp[8] : name | 1497 // -- rsp[8] : name |
| 1498 // -- rsp[16] : receiver | 1498 // -- rsp[16] : receiver |
| 1499 // ----------------------------------- | 1499 // ----------------------------------- |
| 1500 Label miss; | 1500 Label miss; |
| 1501 | 1501 |
| 1502 __ movq(rax, Operand(rsp, kPointerSize)); | 1502 __ movq(rax, Operand(rsp, kPointerSize)); |
| 1503 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); | 1503 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); |
| 1504 __ IncrementCounter(&Counters::keyed_load_field, 1); | 1504 __ IncrementCounter(&COUNTER(keyed_load_field), 1); |
| 1505 | 1505 |
| 1506 // Check that the name has not changed. | 1506 // Check that the name has not changed. |
| 1507 __ Cmp(rax, Handle<String>(name)); | 1507 __ Cmp(rax, Handle<String>(name)); |
| 1508 __ j(not_equal, &miss); | 1508 __ j(not_equal, &miss); |
| 1509 | 1509 |
| 1510 GenerateLoadField(receiver, holder, rcx, rbx, rdx, index, name, &miss); | 1510 GenerateLoadField(receiver, holder, rcx, rbx, rdx, index, name, &miss); |
| 1511 | 1511 |
| 1512 __ bind(&miss); | 1512 __ bind(&miss); |
| 1513 __ DecrementCounter(&Counters::keyed_load_field, 1); | 1513 __ DecrementCounter(&COUNTER(keyed_load_field), 1); |
| 1514 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1514 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1515 | 1515 |
| 1516 // Return the generated code. | 1516 // Return the generated code. |
| 1517 return GetCode(FIELD, name); | 1517 return GetCode(FIELD, name); |
| 1518 } | 1518 } |
| 1519 | 1519 |
| 1520 | 1520 |
| 1521 Object* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 1521 Object* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
| 1522 int index, | 1522 int index, |
| 1523 Map* transition, | 1523 Map* transition, |
| 1524 String* name) { | 1524 String* name) { |
| 1525 // ----------- S t a t e ------------- | 1525 // ----------- S t a t e ------------- |
| 1526 // -- rax : value | 1526 // -- rax : value |
| 1527 // -- rsp[0] : return address | 1527 // -- rsp[0] : return address |
| 1528 // -- rsp[8] : key | 1528 // -- rsp[8] : key |
| 1529 // -- rsp[16] : receiver | 1529 // -- rsp[16] : receiver |
| 1530 // ----------------------------------- | 1530 // ----------------------------------- |
| 1531 Label miss; | 1531 Label miss; |
| 1532 | 1532 |
| 1533 __ IncrementCounter(&Counters::keyed_store_field, 1); | 1533 __ IncrementCounter(&COUNTER(keyed_store_field), 1); |
| 1534 | 1534 |
| 1535 // Get the name from the stack. | 1535 // Get the name from the stack. |
| 1536 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); | 1536 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); |
| 1537 // Check that the name has not changed. | 1537 // Check that the name has not changed. |
| 1538 __ Cmp(rcx, Handle<String>(name)); | 1538 __ Cmp(rcx, Handle<String>(name)); |
| 1539 __ j(not_equal, &miss); | 1539 __ j(not_equal, &miss); |
| 1540 | 1540 |
| 1541 // Get the object from the stack. | 1541 // Get the object from the stack. |
| 1542 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); | 1542 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); |
| 1543 | 1543 |
| 1544 // Generate store field code. Trashes the name register. | 1544 // Generate store field code. Trashes the name register. |
| 1545 GenerateStoreField(masm(), | 1545 GenerateStoreField(masm(), |
| 1546 Builtins::KeyedStoreIC_ExtendStorage, | 1546 Builtins::KeyedStoreIC_ExtendStorage, |
| 1547 object, | 1547 object, |
| 1548 index, | 1548 index, |
| 1549 transition, | 1549 transition, |
| 1550 rbx, rcx, rdx, | 1550 rbx, rcx, rdx, |
| 1551 &miss); | 1551 &miss); |
| 1552 | 1552 |
| 1553 // Handle store cache miss. | 1553 // Handle store cache miss. |
| 1554 __ bind(&miss); | 1554 __ bind(&miss); |
| 1555 __ DecrementCounter(&Counters::keyed_store_field, 1); | 1555 __ DecrementCounter(&COUNTER(keyed_store_field), 1); |
| 1556 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 1556 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); |
| 1557 __ Jump(ic, RelocInfo::CODE_TARGET); | 1557 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 1558 | 1558 |
| 1559 // Return the generated code. | 1559 // Return the generated code. |
| 1560 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 1560 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
| 1561 } | 1561 } |
| 1562 | 1562 |
| 1563 | 1563 |
| 1564 // TODO(1241006): Avoid having lazy compile stubs specialized by the | 1564 // TODO(1241006): Avoid having lazy compile stubs specialized by the |
| 1565 // number of arguments. It is not needed anymore. | 1565 // number of arguments. It is not needed anymore. |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1833 __ movq(rbx, rax); | 1833 __ movq(rbx, rax); |
| 1834 __ movq(rax, rdx); | 1834 __ movq(rax, rdx); |
| 1835 __ or_(rax, Immediate(kHeapObjectTag)); | 1835 __ or_(rax, Immediate(kHeapObjectTag)); |
| 1836 | 1836 |
| 1837 // rax: JSObject | 1837 // rax: JSObject |
| 1838 // rbx: argc | 1838 // rbx: argc |
| 1839 // Remove caller arguments and receiver from the stack and return. | 1839 // Remove caller arguments and receiver from the stack and return. |
| 1840 __ pop(rcx); | 1840 __ pop(rcx); |
| 1841 __ lea(rsp, Operand(rsp, rbx, times_pointer_size, 1 * kPointerSize)); | 1841 __ lea(rsp, Operand(rsp, rbx, times_pointer_size, 1 * kPointerSize)); |
| 1842 __ push(rcx); | 1842 __ push(rcx); |
| 1843 __ IncrementCounter(&Counters::constructed_objects, 1); | 1843 __ IncrementCounter(&COUNTER(constructed_objects), 1); |
| 1844 __ IncrementCounter(&Counters::constructed_objects_stub, 1); | 1844 __ IncrementCounter(&COUNTER(constructed_objects_stub), 1); |
| 1845 __ ret(0); | 1845 __ ret(0); |
| 1846 | 1846 |
| 1847 // Jump to the generic stub in case the specialized code cannot handle the | 1847 // Jump to the generic stub in case the specialized code cannot handle the |
| 1848 // construction. | 1848 // construction. |
| 1849 __ bind(&generic_stub_call); | 1849 __ bind(&generic_stub_call); |
| 1850 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); | 1850 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); |
| 1851 Handle<Code> generic_construct_stub(code); | 1851 Handle<Code> generic_construct_stub(code); |
| 1852 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 1852 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 1853 | 1853 |
| 1854 // Return the generated code. | 1854 // Return the generated code. |
| 1855 return GetCode(); | 1855 return GetCode(); |
| 1856 } | 1856 } |
| 1857 | 1857 |
| 1858 | 1858 |
| 1859 #undef __ | 1859 #undef __ |
| 1860 | 1860 |
| 1861 } } // namespace v8::internal | 1861 } } // namespace v8::internal |
| OLD | NEW |