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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 1148007: Merge bleeding_edge from version 2.1.3 up to revision 4205... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: Created 10 years, 9 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
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 if (function == NULL || !function->is_compiled()) return; 542 if (function == NULL || !function->is_compiled()) return;
543 543
544 constant_function_ = function; 544 constant_function_ = function;
545 AnalyzePossibleApiFunction(function); 545 AnalyzePossibleApiFunction(function);
546 } 546 }
547 547
548 // Determines whether the given function can be called using the 548 // Determines whether the given function can be called using the
549 // fast api call builtin. 549 // fast api call builtin.
550 void AnalyzePossibleApiFunction(JSFunction* function) { 550 void AnalyzePossibleApiFunction(JSFunction* function) {
551 SharedFunctionInfo* sfi = function->shared(); 551 SharedFunctionInfo* sfi = function->shared();
552 if (sfi->function_data()->IsUndefined()) return; 552 if (!sfi->IsApiFunction()) return;
553 FunctionTemplateInfo* info = 553 FunctionTemplateInfo* info = sfi->get_api_func_data();
554 FunctionTemplateInfo::cast(sfi->function_data());
555 554
556 // Require a C++ callback. 555 // Require a C++ callback.
557 if (info->call_code()->IsUndefined()) return; 556 if (info->call_code()->IsUndefined()) return;
558 api_call_info_ = CallHandlerInfo::cast(info->call_code()); 557 api_call_info_ = CallHandlerInfo::cast(info->call_code());
559 558
560 // Accept signatures that either have no restrictions at all or 559 // Accept signatures that either have no restrictions at all or
561 // only have restrictions on the receiver. 560 // only have restrictions on the receiver.
562 if (!info->signature()->IsUndefined()) { 561 if (!info->signature()->IsUndefined()) {
563 SignatureInfo* signature = SignatureInfo::cast(info->signature()); 562 SignatureInfo* signature = SignatureInfo::cast(info->signature());
564 if (!signature->args()->IsUndefined()) return; 563 if (!signature->args()->IsUndefined()) return;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 Label* miss) { 690 Label* miss) {
692 ASSERT(holder->HasNamedInterceptor()); 691 ASSERT(holder->HasNamedInterceptor());
693 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 692 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
694 693
695 // Check that the receiver isn't a smi. 694 // Check that the receiver isn't a smi.
696 __ test(receiver, Immediate(kSmiTagMask)); 695 __ test(receiver, Immediate(kSmiTagMask));
697 __ j(zero, miss, not_taken); 696 __ j(zero, miss, not_taken);
698 697
699 CallOptimization optimization(lookup); 698 CallOptimization optimization(lookup);
700 699
701 if (optimization.is_constant_call() && 700 if (optimization.is_constant_call()) {
702 !Top::CanHaveSpecialFunctions(holder)) {
703 CompileCacheable(masm, 701 CompileCacheable(masm,
704 object, 702 object,
705 receiver, 703 receiver,
706 scratch1, 704 scratch1,
707 scratch2, 705 scratch2,
708 holder, 706 holder,
709 lookup, 707 lookup,
710 name, 708 name,
711 optimization, 709 optimization,
712 miss); 710 miss);
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 // Handle call cache miss. 1202 // Handle call cache miss.
1205 __ bind(&miss); 1203 __ bind(&miss);
1206 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); 1204 Handle<Code> ic = ComputeCallMiss(arguments().immediate());
1207 __ jmp(ic, RelocInfo::CODE_TARGET); 1205 __ jmp(ic, RelocInfo::CODE_TARGET);
1208 1206
1209 // Return the generated code. 1207 // Return the generated code.
1210 return GetCode(FIELD, name); 1208 return GetCode(FIELD, name);
1211 } 1209 }
1212 1210
1213 1211
1212 Object* CallStubCompiler::CompileArrayPushCall(Object* object,
1213 JSObject* holder,
1214 JSFunction* function,
1215 String* name,
1216 CheckType check) {
1217 // ----------- S t a t e -------------
1218 // -- ecx : name
1219 // -- esp[0] : return address
1220 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1221 // -- ...
1222 // -- esp[(argc + 1) * 4] : receiver
1223 // -----------------------------------
1224 ASSERT(check == RECEIVER_MAP_CHECK);
1225
1226 Label miss;
1227
1228 // Get the receiver from the stack.
1229 const int argc = arguments().immediate();
1230 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1231
1232 // Check that the receiver isn't a smi.
1233 __ test(edx, Immediate(kSmiTagMask));
1234 __ j(zero, &miss);
1235
1236 CheckPrototypes(JSObject::cast(object), edx,
1237 holder, ebx,
1238 eax, name, &miss);
1239
1240 if (argc == 0) {
1241 // Noop, return the length.
1242 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1243 __ ret((argc + 1) * kPointerSize);
1244 } else {
1245 // Get the elements array of the object.
1246 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1247
1248 // Check that the elements are in fast mode (not dictionary).
1249 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1250 Immediate(Factory::fixed_array_map()));
1251 __ j(not_equal, &miss);
1252
1253 if (argc == 1) { // Otherwise fall through to call builtin.
1254 Label call_builtin, exit, with_rset_update,
1255 attempt_to_grow_elements, finish_push;
1256
1257 // Get the array's length into eax and calculate new length.
1258 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1259 STATIC_ASSERT(kSmiTagSize == 1);
1260 STATIC_ASSERT(kSmiTag == 0);
1261 __ add(Operand(eax), Immediate(argc << 1));
1262
1263 // Get the element's length into ecx.
1264 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
1265 __ SmiTag(ecx);
1266
1267 // Check if we could survive without allocation.
1268 __ cmp(eax, Operand(ecx));
1269 __ j(greater, &attempt_to_grow_elements);
1270
1271 // Save new length.
1272 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1273
1274 // Push the element.
1275 __ lea(edx, FieldOperand(ebx,
1276 eax, times_half_pointer_size,
1277 FixedArray::kHeaderSize - argc * kPointerSize));
1278 __ mov(ecx, Operand(esp, argc * kPointerSize));
1279 __ mov(Operand(edx, 0), ecx);
1280
1281 __ bind(&finish_push);
1282
1283 // Check if value is a smi.
1284 __ test(ecx, Immediate(kSmiTagMask));
1285 __ j(not_zero, &with_rset_update);
1286
1287 __ bind(&exit);
1288 __ ret((argc + 1) * kPointerSize);
1289
1290 __ bind(&with_rset_update);
1291
1292 __ InNewSpace(ebx, ecx, equal, &exit);
1293
1294 RecordWriteStub stub(ebx, edx, ecx);
1295 __ CallStub(&stub);
1296 __ ret((argc + 1) * kPointerSize);
1297
1298 __ bind(&attempt_to_grow_elements);
1299 ExternalReference new_space_allocation_top =
1300 ExternalReference::new_space_allocation_top_address();
1301 ExternalReference new_space_allocation_limit =
1302 ExternalReference::new_space_allocation_limit_address();
1303
1304 const int kAllocationDelta = 4;
1305 // Load top.
1306 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top));
1307
1308 // Check if it's the end of elements.
1309 __ lea(edx, FieldOperand(ebx,
1310 eax, times_half_pointer_size,
1311 FixedArray::kHeaderSize - argc * kPointerSize));
1312 __ cmp(edx, Operand(ecx));
1313 __ j(not_equal, &call_builtin);
1314 __ add(Operand(ecx), Immediate(kAllocationDelta * kPointerSize));
1315 __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit));
1316 __ j(greater, &call_builtin);
1317
1318 // We fit and could grow elements.
1319 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
1320 __ mov(ecx, Operand(esp, argc * kPointerSize));
1321 __ mov(Operand(edx, 0), ecx);
1322 for (int i = 1; i < kAllocationDelta; i++) {
1323 __ mov(Operand(edx, i * kPointerSize),
1324 Immediate(Factory::undefined_value()));
1325 }
1326
1327 // Restore receiver to edx as finish sequence assumes it's here.
1328 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1329
1330 // Increment element's and array's sizes.
1331 __ add(FieldOperand(ebx, FixedArray::kLengthOffset),
1332 Immediate(kAllocationDelta));
1333 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1334
1335 __ jmp(&finish_push);
1336
1337 __ bind(&call_builtin);
1338 }
1339
1340 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush),
1341 argc + 1,
1342 1);
1343 }
1344
1345 __ bind(&miss);
1346
1347 Handle<Code> ic = ComputeCallMiss(arguments().immediate());
1348 __ jmp(ic, RelocInfo::CODE_TARGET);
1349
1350 // Return the generated code.
1351 String* function_name = NULL;
1352 if (function->shared()->name()->IsString()) {
1353 function_name = String::cast(function->shared()->name());
1354 }
1355 return GetCode(CONSTANT_FUNCTION, function_name);
1356 }
1357
1358
1359 Object* CallStubCompiler::CompileArrayPopCall(Object* object,
1360 JSObject* holder,
1361 JSFunction* function,
1362 String* name,
1363 CheckType check) {
1364 // ----------- S t a t e -------------
1365 // -- ecx : name
1366 // -- esp[0] : return address
1367 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1368 // -- ...
1369 // -- esp[(argc + 1) * 4] : receiver
1370 // -----------------------------------
1371 ASSERT(check == RECEIVER_MAP_CHECK);
1372
1373 Label miss, empty_array, call_builtin;
1374
1375 // Get the receiver from the stack.
1376 const int argc = arguments().immediate();
1377 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1378
1379 // Check that the receiver isn't a smi.
1380 __ test(edx, Immediate(kSmiTagMask));
1381 __ j(zero, &miss);
1382
1383 CheckPrototypes(JSObject::cast(object), edx,
1384 holder, ebx,
1385 eax, name, &miss);
1386
1387 // Get the elements array of the object.
1388 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1389
1390 // Check that the elements are in fast mode (not dictionary).
1391 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1392 Immediate(Factory::fixed_array_map()));
1393 __ j(not_equal, &miss);
1394
1395 // Get the array's length into ecx and calculate new length.
1396 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset));
1397 __ sub(Operand(ecx), Immediate(Smi::FromInt(1)));
1398 __ j(negative, &empty_array);
1399
1400 // Get the last element.
1401 STATIC_ASSERT(kSmiTagSize == 1);
1402 STATIC_ASSERT(kSmiTag == 0);
1403 __ mov(eax, FieldOperand(ebx,
1404 ecx, times_half_pointer_size,
1405 FixedArray::kHeaderSize));
1406 __ cmp(Operand(eax), Immediate(Factory::the_hole_value()));
1407 __ j(equal, &call_builtin);
1408
1409 // Set the array's length.
1410 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx);
1411
1412 // Fill with the hole.
1413 __ mov(FieldOperand(ebx,
1414 ecx, times_half_pointer_size,
1415 FixedArray::kHeaderSize),
1416 Immediate(Factory::the_hole_value()));
1417 __ ret((argc + 1) * kPointerSize);
1418
1419 __ bind(&empty_array);
1420 __ mov(eax, Immediate(Factory::undefined_value()));
1421 __ ret((argc + 1) * kPointerSize);
1422
1423 __ bind(&call_builtin);
1424
1425 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop),
1426 argc + 1,
1427 1);
1428
1429 __ bind(&miss);
1430
1431 Handle<Code> ic = ComputeCallMiss(arguments().immediate());
1432 __ jmp(ic, RelocInfo::CODE_TARGET);
1433
1434 // Return the generated code.
1435 String* function_name = NULL;
1436 if (function->shared()->name()->IsString()) {
1437 function_name = String::cast(function->shared()->name());
1438 }
1439 return GetCode(CONSTANT_FUNCTION, function_name);
1440 }
1441
1442
1214 Object* CallStubCompiler::CompileCallConstant(Object* object, 1443 Object* CallStubCompiler::CompileCallConstant(Object* object,
1215 JSObject* holder, 1444 JSObject* holder,
1216 JSFunction* function, 1445 JSFunction* function,
1217 String* name, 1446 String* name,
1218 CheckType check) { 1447 CheckType check) {
1219 // ----------- S t a t e ------------- 1448 // ----------- S t a t e -------------
1220 // -- ecx : name 1449 // -- ecx : name
1221 // -- esp[0] : return address 1450 // -- esp[0] : return address
1222 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1451 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1223 // -- ... 1452 // -- ...
1224 // -- esp[(argc + 1) * 4] : receiver 1453 // -- esp[(argc + 1) * 4] : receiver
1225 // ----------------------------------- 1454 // -----------------------------------
1455
1456 SharedFunctionInfo* function_info = function->shared();
1457 if (false && function_info->HasCustomCallGenerator()) {
1458 CustomCallGenerator generator =
1459 ToCData<CustomCallGenerator>(function_info->function_data());
1460 return generator(this, object, holder, function, name, check);
1461 }
1462
1226 Label miss_in_smi_check; 1463 Label miss_in_smi_check;
1227 1464
1228 // Get the receiver from the stack. 1465 // Get the receiver from the stack.
1229 const int argc = arguments().immediate(); 1466 const int argc = arguments().immediate();
1230 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1467 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1231 1468
1232 // Check that the receiver isn't a smi. 1469 // Check that the receiver isn't a smi.
1233 if (check != NUMBER_CHECK) { 1470 if (check != NUMBER_CHECK) {
1234 __ test(edx, Immediate(kSmiTagMask)); 1471 __ test(edx, Immediate(kSmiTagMask));
1235 __ j(zero, &miss_in_smi_check, not_taken); 1472 __ j(zero, &miss_in_smi_check, not_taken);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 // Check that the maps starting from the prototype haven't changed. 1563 // Check that the maps starting from the prototype haven't changed.
1327 GenerateLoadGlobalFunctionPrototype(masm(), 1564 GenerateLoadGlobalFunctionPrototype(masm(),
1328 Context::BOOLEAN_FUNCTION_INDEX, 1565 Context::BOOLEAN_FUNCTION_INDEX,
1329 eax); 1566 eax);
1330 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 1567 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
1331 ebx, edx, name, &miss); 1568 ebx, edx, name, &miss);
1332 } 1569 }
1333 break; 1570 break;
1334 } 1571 }
1335 1572
1336 case JSARRAY_HAS_FAST_ELEMENTS_CHECK:
1337 CheckPrototypes(JSObject::cast(object), edx, holder,
1338 ebx, eax, name, &miss);
1339 // Make sure object->HasFastElements().
1340 // Get the elements array of the object.
1341 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
1342 // Check that the object is in fast mode (not dictionary).
1343 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1344 Immediate(Factory::fixed_array_map()));
1345 __ j(not_equal, &miss, not_taken);
1346 break;
1347
1348 default: 1573 default:
1349 UNREACHABLE(); 1574 UNREACHABLE();
1350 } 1575 }
1351 1576
1352 if (depth != kInvalidProtoDepth) { 1577 if (depth != kInvalidProtoDepth) {
1353 GenerateFastApiCall(masm(), optimization, argc); 1578 GenerateFastApiCall(masm(), optimization, argc);
1354 } else { 1579 } else {
1355 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); 1580 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
1356 } 1581 }
1357 1582
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after
2199 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 2424 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
2200 2425
2201 // Return the generated code. 2426 // Return the generated code.
2202 return GetCode(); 2427 return GetCode();
2203 } 2428 }
2204 2429
2205 2430
2206 #undef __ 2431 #undef __
2207 2432
2208 } } // namespace v8::internal 2433 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698