| 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 |