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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 | 285 |
286 if (check != RECEIVER_MAP_CHECK && | 286 if (check != RECEIVER_MAP_CHECK && |
287 !function->IsBuiltin() && | 287 !function->IsBuiltin() && |
288 function->shared()->is_classic_mode()) { | 288 function->shared()->is_classic_mode()) { |
289 // Calling non-strict non-builtins with a value as the receiver | 289 // Calling non-strict non-builtins with a value as the receiver |
290 // requires boxing. | 290 // requires boxing. |
291 return Handle<Code>::null(); | 291 return Handle<Code>::null(); |
292 } | 292 } |
293 | 293 |
294 Code::Flags flags = Code::ComputeMonomorphicFlags( | 294 Code::Flags flags = Code::ComputeMonomorphicFlags( |
295 kind, extra_state, cache_holder, Code::CONSTANT, argc); | 295 kind, extra_state, cache_holder, Code::FAST, argc); |
296 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 296 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
297 isolate_); | 297 isolate_); |
298 if (probe->IsCode()) return Handle<Code>::cast(probe); | 298 if (probe->IsCode()) return Handle<Code>::cast(probe); |
299 | 299 |
300 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); | 300 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); |
301 Handle<Code> code = | 301 Handle<Code> code = |
302 compiler.CompileCallConstant(object, holder, name, check, function); | 302 compiler.CompileCallConstant(object, holder, name, check, function); |
303 code->set_check_type(check); | 303 code->set_check_type(check); |
304 ASSERT(flags == code->flags()); | 304 ASSERT(flags == code->flags()); |
305 PROFILE(isolate_, | 305 PROFILE(isolate_, |
(...skipping 21 matching lines...) Expand all Loading... |
327 | 327 |
328 // TODO(1233596): We cannot do receiver map check for non-JS objects | 328 // TODO(1233596): We cannot do receiver map check for non-JS objects |
329 // because they may be represented as immediates without a | 329 // because they may be represented as immediates without a |
330 // map. Instead, we check against the map in the holder. | 330 // map. Instead, we check against the map in the holder. |
331 if (object->IsNumber() || object->IsSymbol() || | 331 if (object->IsNumber() || object->IsSymbol() || |
332 object->IsBoolean() || object->IsString()) { | 332 object->IsBoolean() || object->IsString()) { |
333 object = holder; | 333 object = holder; |
334 } | 334 } |
335 | 335 |
336 Code::Flags flags = Code::ComputeMonomorphicFlags( | 336 Code::Flags flags = Code::ComputeMonomorphicFlags( |
337 kind, extra_state, cache_holder, Code::FIELD, argc); | 337 kind, extra_state, cache_holder, Code::FAST, argc); |
338 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 338 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
339 isolate_); | 339 isolate_); |
340 if (probe->IsCode()) return Handle<Code>::cast(probe); | 340 if (probe->IsCode()) return Handle<Code>::cast(probe); |
341 | 341 |
342 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); | 342 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); |
343 Handle<Code> code = | 343 Handle<Code> code = |
344 compiler.CompileCallField(Handle<JSObject>::cast(object), | 344 compiler.CompileCallField(Handle<JSObject>::cast(object), |
345 holder, index, name); | 345 holder, index, name); |
346 ASSERT(flags == code->flags()); | 346 ASSERT(flags == code->flags()); |
347 PROFILE(isolate_, | 347 PROFILE(isolate_, |
(...skipping 17 matching lines...) Expand all Loading... |
365 | 365 |
366 // TODO(1233596): We cannot do receiver map check for non-JS objects | 366 // TODO(1233596): We cannot do receiver map check for non-JS objects |
367 // because they may be represented as immediates without a | 367 // because they may be represented as immediates without a |
368 // map. Instead, we check against the map in the holder. | 368 // map. Instead, we check against the map in the holder. |
369 if (object->IsNumber() || object->IsSymbol() || | 369 if (object->IsNumber() || object->IsSymbol() || |
370 object->IsBoolean() || object->IsString()) { | 370 object->IsBoolean() || object->IsString()) { |
371 object = holder; | 371 object = holder; |
372 } | 372 } |
373 | 373 |
374 Code::Flags flags = Code::ComputeMonomorphicFlags( | 374 Code::Flags flags = Code::ComputeMonomorphicFlags( |
375 kind, extra_state, cache_holder, Code::INTERCEPTOR, argc); | 375 kind, extra_state, cache_holder, Code::FAST, argc); |
376 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 376 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
377 isolate_); | 377 isolate_); |
378 if (probe->IsCode()) return Handle<Code>::cast(probe); | 378 if (probe->IsCode()) return Handle<Code>::cast(probe); |
379 | 379 |
380 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); | 380 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); |
381 Handle<Code> code = | 381 Handle<Code> code = |
382 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object), | 382 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object), |
383 holder, name); | 383 holder, name); |
384 ASSERT(flags == code->flags()); | 384 ASSERT(flags == code->flags()); |
385 PROFILE(isolate(), | 385 PROFILE(isolate(), |
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1252 Label miss; | 1252 Label miss; |
1253 | 1253 |
1254 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); | 1254 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); |
1255 | 1255 |
1256 GenerateLoadField(reg, holder, field, representation); | 1256 GenerateLoadField(reg, holder, field, representation); |
1257 | 1257 |
1258 __ bind(&miss); | 1258 __ bind(&miss); |
1259 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1259 TailCallBuiltin(masm(), MissBuiltin(kind())); |
1260 | 1260 |
1261 // Return the generated code. | 1261 // Return the generated code. |
1262 return GetCode(kind(), Code::FIELD, name); | 1262 return GetCode(kind(), Code::FAST, name); |
1263 } | 1263 } |
1264 | 1264 |
1265 | 1265 |
1266 Handle<Code> LoadStubCompiler::CompileLoadConstant( | 1266 Handle<Code> LoadStubCompiler::CompileLoadConstant( |
1267 Handle<Object> object, | 1267 Handle<Object> object, |
1268 Handle<JSObject> holder, | 1268 Handle<JSObject> holder, |
1269 Handle<Name> name, | 1269 Handle<Name> name, |
1270 Handle<Object> value) { | 1270 Handle<Object> value) { |
1271 HandlerFrontend(object, receiver(), holder, name); | 1271 HandlerFrontend(object, receiver(), holder, name); |
1272 GenerateLoadConstant(value); | 1272 GenerateLoadConstant(value); |
1273 | 1273 |
1274 // Return the generated code. | 1274 // Return the generated code. |
1275 return GetCode(kind(), Code::CONSTANT, name); | 1275 return GetCode(kind(), Code::FAST, name); |
1276 } | 1276 } |
1277 | 1277 |
1278 | 1278 |
1279 Handle<Code> LoadStubCompiler::CompileLoadCallback( | 1279 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
1280 Handle<Object> object, | 1280 Handle<Object> object, |
1281 Handle<JSObject> holder, | 1281 Handle<JSObject> holder, |
1282 Handle<Name> name, | 1282 Handle<Name> name, |
1283 Handle<ExecutableAccessorInfo> callback) { | 1283 Handle<ExecutableAccessorInfo> callback) { |
1284 Register reg = CallbackHandlerFrontend( | 1284 Register reg = CallbackHandlerFrontend( |
1285 object, receiver(), holder, name, callback); | 1285 object, receiver(), holder, name, callback); |
1286 GenerateLoadCallback(reg, callback); | 1286 GenerateLoadCallback(reg, callback); |
1287 | 1287 |
1288 // Return the generated code. | 1288 // Return the generated code. |
1289 return GetCode(kind(), Code::CALLBACKS, name); | 1289 return GetCode(kind(), Code::FAST, name); |
1290 } | 1290 } |
1291 | 1291 |
1292 | 1292 |
1293 Handle<Code> LoadStubCompiler::CompileLoadCallback( | 1293 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
1294 Handle<Object> object, | 1294 Handle<Object> object, |
1295 Handle<JSObject> holder, | 1295 Handle<JSObject> holder, |
1296 Handle<Name> name, | 1296 Handle<Name> name, |
1297 const CallOptimization& call_optimization) { | 1297 const CallOptimization& call_optimization) { |
1298 ASSERT(call_optimization.is_simple_api_call()); | 1298 ASSERT(call_optimization.is_simple_api_call()); |
1299 Handle<JSFunction> callback = call_optimization.constant_function(); | 1299 Handle<JSFunction> callback = call_optimization.constant_function(); |
1300 CallbackHandlerFrontend(object, receiver(), holder, name, callback); | 1300 CallbackHandlerFrontend(object, receiver(), holder, name, callback); |
1301 GenerateLoadCallback(call_optimization); | 1301 GenerateLoadCallback(call_optimization); |
1302 | 1302 |
1303 // Return the generated code. | 1303 // Return the generated code. |
1304 return GetCode(kind(), Code::CALLBACKS, name); | 1304 return GetCode(kind(), Code::FAST, name); |
1305 } | 1305 } |
1306 | 1306 |
1307 | 1307 |
1308 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( | 1308 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( |
1309 Handle<Object> object, | 1309 Handle<Object> object, |
1310 Handle<JSObject> holder, | 1310 Handle<JSObject> holder, |
1311 Handle<Name> name) { | 1311 Handle<Name> name) { |
1312 LookupResult lookup(isolate()); | 1312 LookupResult lookup(isolate()); |
1313 LookupPostInterceptor(holder, name, &lookup); | 1313 LookupPostInterceptor(holder, name, &lookup); |
1314 | 1314 |
1315 Register reg = HandlerFrontend(object, receiver(), holder, name); | 1315 Register reg = HandlerFrontend(object, receiver(), holder, name); |
1316 // TODO(368): Compile in the whole chain: all the interceptors in | 1316 // TODO(368): Compile in the whole chain: all the interceptors in |
1317 // prototypes and ultimate answer. | 1317 // prototypes and ultimate answer. |
1318 GenerateLoadInterceptor(reg, object, holder, &lookup, name); | 1318 GenerateLoadInterceptor(reg, object, holder, &lookup, name); |
1319 | 1319 |
1320 // Return the generated code. | 1320 // Return the generated code. |
1321 return GetCode(kind(), Code::INTERCEPTOR, name); | 1321 return GetCode(kind(), Code::FAST, name); |
1322 } | 1322 } |
1323 | 1323 |
1324 | 1324 |
1325 void LoadStubCompiler::GenerateLoadPostInterceptor( | 1325 void LoadStubCompiler::GenerateLoadPostInterceptor( |
1326 Register interceptor_reg, | 1326 Register interceptor_reg, |
1327 Handle<JSObject> interceptor_holder, | 1327 Handle<JSObject> interceptor_holder, |
1328 Handle<Name> name, | 1328 Handle<Name> name, |
1329 LookupResult* lookup) { | 1329 LookupResult* lookup) { |
1330 Handle<JSObject> holder(lookup->holder()); | 1330 Handle<JSObject> holder(lookup->holder()); |
1331 if (lookup->IsField()) { | 1331 if (lookup->IsField()) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 | 1371 |
1372 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 1372 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( |
1373 Handle<Object> object, | 1373 Handle<Object> object, |
1374 Handle<JSObject> holder, | 1374 Handle<JSObject> holder, |
1375 Handle<Name> name, | 1375 Handle<Name> name, |
1376 Handle<JSFunction> getter) { | 1376 Handle<JSFunction> getter) { |
1377 HandlerFrontend(object, receiver(), holder, name); | 1377 HandlerFrontend(object, receiver(), holder, name); |
1378 GenerateLoadViaGetter(masm(), receiver(), getter); | 1378 GenerateLoadViaGetter(masm(), receiver(), getter); |
1379 | 1379 |
1380 // Return the generated code. | 1380 // Return the generated code. |
1381 return GetCode(kind(), Code::CALLBACKS, name); | 1381 return GetCode(kind(), Code::FAST, name); |
1382 } | 1382 } |
1383 | 1383 |
1384 | 1384 |
1385 Handle<Code> StoreStubCompiler::CompileStoreTransition( | 1385 Handle<Code> StoreStubCompiler::CompileStoreTransition( |
1386 Handle<JSObject> object, | 1386 Handle<JSObject> object, |
1387 LookupResult* lookup, | 1387 LookupResult* lookup, |
1388 Handle<Map> transition, | 1388 Handle<Map> transition, |
1389 Handle<Name> name) { | 1389 Handle<Name> name) { |
1390 Label miss, slow; | 1390 Label miss, slow; |
1391 | 1391 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 &slow); | 1428 &slow); |
1429 | 1429 |
1430 // Handle store cache miss. | 1430 // Handle store cache miss. |
1431 GenerateRestoreName(masm(), &miss, name); | 1431 GenerateRestoreName(masm(), &miss, name); |
1432 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1432 TailCallBuiltin(masm(), MissBuiltin(kind())); |
1433 | 1433 |
1434 GenerateRestoreName(masm(), &slow, name); | 1434 GenerateRestoreName(masm(), &slow, name); |
1435 TailCallBuiltin(masm(), SlowBuiltin(kind())); | 1435 TailCallBuiltin(masm(), SlowBuiltin(kind())); |
1436 | 1436 |
1437 // Return the generated code. | 1437 // Return the generated code. |
1438 return GetCode(kind(), Code::TRANSITION, name); | 1438 return GetCode(kind(), Code::FAST, name); |
1439 } | 1439 } |
1440 | 1440 |
1441 | 1441 |
1442 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 1442 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
1443 LookupResult* lookup, | 1443 LookupResult* lookup, |
1444 Handle<Name> name) { | 1444 Handle<Name> name) { |
1445 Label miss; | 1445 Label miss; |
1446 | 1446 |
1447 HandlerFrontendHeader(object, receiver(), object, name, &miss); | 1447 HandlerFrontendHeader(object, receiver(), object, name, &miss); |
1448 | 1448 |
1449 // Generate store field code. | 1449 // Generate store field code. |
1450 GenerateStoreField(masm(), | 1450 GenerateStoreField(masm(), |
1451 object, | 1451 object, |
1452 lookup, | 1452 lookup, |
1453 receiver(), this->name(), value(), scratch1(), scratch2(), | 1453 receiver(), this->name(), value(), scratch1(), scratch2(), |
1454 &miss); | 1454 &miss); |
1455 | 1455 |
1456 // Handle store cache miss. | 1456 // Handle store cache miss. |
1457 __ bind(&miss); | 1457 __ bind(&miss); |
1458 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1458 TailCallBuiltin(masm(), MissBuiltin(kind())); |
1459 | 1459 |
1460 // Return the generated code. | 1460 // Return the generated code. |
1461 return GetCode(kind(), Code::FIELD, name); | 1461 return GetCode(kind(), Code::FAST, name); |
1462 } | 1462 } |
1463 | 1463 |
1464 | 1464 |
1465 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | 1465 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( |
1466 Handle<JSObject> object, | 1466 Handle<JSObject> object, |
1467 Handle<JSObject> holder, | 1467 Handle<JSObject> holder, |
1468 Handle<Name> name, | 1468 Handle<Name> name, |
1469 Handle<JSFunction> setter) { | 1469 Handle<JSFunction> setter) { |
1470 HandlerFrontend(object, receiver(), holder, name); | 1470 HandlerFrontend(object, receiver(), holder, name); |
1471 GenerateStoreViaSetter(masm(), setter); | 1471 GenerateStoreViaSetter(masm(), setter); |
1472 | 1472 |
1473 return GetCode(kind(), Code::CALLBACKS, name); | 1473 return GetCode(kind(), Code::FAST, name); |
1474 } | 1474 } |
1475 | 1475 |
1476 | 1476 |
1477 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( | 1477 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( |
1478 Handle<Map> receiver_map) { | 1478 Handle<Map> receiver_map) { |
1479 ElementsKind elements_kind = receiver_map->elements_kind(); | 1479 ElementsKind elements_kind = receiver_map->elements_kind(); |
1480 if (receiver_map->has_fast_elements() || | 1480 if (receiver_map->has_fast_elements() || |
1481 receiver_map->has_external_array_elements()) { | 1481 receiver_map->has_external_array_elements()) { |
1482 Handle<Code> stub = KeyedLoadFastElementStub( | 1482 Handle<Code> stub = KeyedLoadFastElementStub( |
1483 receiver_map->instance_type() == JS_ARRAY_TYPE, | 1483 receiver_map->instance_type() == JS_ARRAY_TYPE, |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1750 kind_, extra_state_, cache_holder_, type, argc); | 1750 kind_, extra_state_, cache_holder_, type, argc); |
1751 return GetCodeWithFlags(flags, name); | 1751 return GetCodeWithFlags(flags, name); |
1752 } | 1752 } |
1753 | 1753 |
1754 | 1754 |
1755 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { | 1755 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { |
1756 Handle<String> function_name; | 1756 Handle<String> function_name; |
1757 if (function->shared()->name()->IsString()) { | 1757 if (function->shared()->name()->IsString()) { |
1758 function_name = Handle<String>(String::cast(function->shared()->name())); | 1758 function_name = Handle<String>(String::cast(function->shared()->name())); |
1759 } | 1759 } |
1760 return GetCode(Code::CONSTANT, function_name); | 1760 return GetCode(Code::FAST, function_name); |
1761 } | 1761 } |
1762 | 1762 |
1763 | 1763 |
1764 CallOptimization::CallOptimization(LookupResult* lookup) { | 1764 CallOptimization::CallOptimization(LookupResult* lookup) { |
1765 if (lookup->IsFound() && | 1765 if (lookup->IsFound() && |
1766 lookup->IsCacheable() && | 1766 lookup->IsCacheable() && |
1767 lookup->IsConstantFunction()) { | 1767 lookup->IsConstantFunction()) { |
1768 // We only optimize constant function calls. | 1768 // We only optimize constant function calls. |
1769 Initialize(Handle<JSFunction>(lookup->GetConstantFunction())); | 1769 Initialize(Handle<JSFunction>(lookup->GetConstantFunction())); |
1770 } else { | 1770 } else { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1828 Handle<FunctionTemplateInfo>( | 1828 Handle<FunctionTemplateInfo>( |
1829 FunctionTemplateInfo::cast(signature->receiver())); | 1829 FunctionTemplateInfo::cast(signature->receiver())); |
1830 } | 1830 } |
1831 } | 1831 } |
1832 | 1832 |
1833 is_simple_api_call_ = true; | 1833 is_simple_api_call_ = true; |
1834 } | 1834 } |
1835 | 1835 |
1836 | 1836 |
1837 } } // namespace v8::internal | 1837 } } // namespace v8::internal |
OLD | NEW |