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

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

Issue 844006: Merge changes up to V8 version 2.1.3 into the partial snapshots (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
« no previous file with comments | « src/ia32/register-allocator-ia32.cc ('k') | src/ia32/virtual-frame-ia32.h » ('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 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 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 __ pop(scratch2); // save old return address 439 __ pop(scratch2); // save old return address
440 __ push(holder); 440 __ push(holder);
441 __ mov(holder, Immediate(Handle<AccessorInfo>(callback))); 441 __ mov(holder, Immediate(Handle<AccessorInfo>(callback)));
442 __ push(holder); 442 __ push(holder);
443 __ push(FieldOperand(holder, AccessorInfo::kDataOffset)); 443 __ push(FieldOperand(holder, AccessorInfo::kDataOffset));
444 __ push(name_); 444 __ push(name_);
445 __ push(scratch2); // restore old return address 445 __ push(scratch2); // restore old return address
446 446
447 ExternalReference ref = 447 ExternalReference ref =
448 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); 448 ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
449 __ TailCallRuntime(ref, 5, 1); 449 __ TailCallExternalReference(ref, 5, 1);
450 450
451 __ bind(&cleanup); 451 __ bind(&cleanup);
452 __ pop(scratch1); 452 __ pop(scratch1);
453 __ pop(scratch2); 453 __ pop(scratch2);
454 __ push(scratch1); 454 __ push(scratch1);
455 } 455 }
456 } 456 }
457 457
458 458
459 void CompileRegular(MacroAssembler* masm, 459 void CompileRegular(MacroAssembler* masm,
460 Register receiver, 460 Register receiver,
461 Register holder, 461 Register holder,
462 Register scratch, 462 Register scratch,
463 JSObject* holder_obj, 463 JSObject* holder_obj,
464 Label* miss_label) { 464 Label* miss_label) {
465 __ pop(scratch); // save old return address 465 __ pop(scratch); // save old return address
466 PushInterceptorArguments(masm, receiver, holder, name_, holder_obj); 466 PushInterceptorArguments(masm, receiver, holder, name_, holder_obj);
467 __ push(scratch); // restore old return address 467 __ push(scratch); // restore old return address
468 468
469 ExternalReference ref = ExternalReference( 469 ExternalReference ref = ExternalReference(
470 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad)); 470 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
471 __ TailCallRuntime(ref, 5, 1); 471 __ TailCallExternalReference(ref, 5, 1);
472 } 472 }
473 473
474 private: 474 private:
475 Register name_; 475 Register name_;
476 }; 476 };
477 477
478 478
479 // Holds information about possible function call optimizations. 479 // Holds information about possible function call optimizations.
480 class CallOptimization BASE_EMBEDDED { 480 class CallOptimization BASE_EMBEDDED {
481 public: 481 public:
482 explicit CallOptimization(LookupResult* lookup) 482 explicit CallOptimization(LookupResult* lookup) {
483 : constant_function_(NULL), 483 if (!lookup->IsProperty() || !lookup->IsCacheable() ||
484 is_simple_api_call_(false), 484 lookup->type() != CONSTANT_FUNCTION) {
485 expected_receiver_type_(NULL), 485 Initialize(NULL);
486 api_call_info_(NULL) { 486 } else {
487 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 487 // We only optimize constant function calls.
488 488 Initialize(lookup->GetConstantFunction());
489 // We only optimize constant function calls. 489 }
490 if (lookup->type() != CONSTANT_FUNCTION) return;
491
492 Initialize(lookup->GetConstantFunction());
493 } 490 }
494 491
495 explicit CallOptimization(JSFunction* function) { 492 explicit CallOptimization(JSFunction* function) {
496 Initialize(function); 493 Initialize(function);
497 } 494 }
498 495
499 bool is_constant_call() const { 496 bool is_constant_call() const {
500 return constant_function_ != NULL; 497 return constant_function_ != NULL;
501 } 498 }
502 499
(...skipping 27 matching lines...) Expand all
530 if (object->IsInstanceOf(expected_receiver_type_)) return depth; 527 if (object->IsInstanceOf(expected_receiver_type_)) return depth;
531 object = JSObject::cast(object->GetPrototype()); 528 object = JSObject::cast(object->GetPrototype());
532 ++depth; 529 ++depth;
533 } 530 }
534 if (holder->IsInstanceOf(expected_receiver_type_)) return depth; 531 if (holder->IsInstanceOf(expected_receiver_type_)) return depth;
535 return kInvalidProtoDepth; 532 return kInvalidProtoDepth;
536 } 533 }
537 534
538 private: 535 private:
539 void Initialize(JSFunction* function) { 536 void Initialize(JSFunction* function) {
540 if (!function->is_compiled()) return; 537 constant_function_ = NULL;
538 is_simple_api_call_ = false;
539 expected_receiver_type_ = NULL;
540 api_call_info_ = NULL;
541
542 if (function == NULL || !function->is_compiled()) return;
541 543
542 constant_function_ = function; 544 constant_function_ = function;
543 is_simple_api_call_ = false;
544
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->function_data()->IsUndefined()) return;
553 FunctionTemplateInfo* info = 553 FunctionTemplateInfo* info =
554 FunctionTemplateInfo::cast(sfi->function_data()); 554 FunctionTemplateInfo::cast(sfi->function_data());
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 900
901 // Perform map transition for the receiver if necessary. 901 // Perform map transition for the receiver if necessary.
902 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { 902 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) {
903 // The properties must be extended before we can store the value. 903 // The properties must be extended before we can store the value.
904 // We jump to a runtime call that extends the properties array. 904 // We jump to a runtime call that extends the properties array.
905 __ pop(scratch); // Return address. 905 __ pop(scratch); // Return address.
906 __ push(receiver_reg); 906 __ push(receiver_reg);
907 __ push(Immediate(Handle<Map>(transition))); 907 __ push(Immediate(Handle<Map>(transition)));
908 __ push(eax); 908 __ push(eax);
909 __ push(scratch); 909 __ push(scratch);
910 __ TailCallRuntime( 910 __ TailCallExternalReference(
911 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), 3, 1); 911 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), 3, 1);
912 return; 912 return;
913 } 913 }
914 914
915 if (transition != NULL) { 915 if (transition != NULL) {
916 // Update the map of the object; no write barrier updating is 916 // Update the map of the object; no write barrier updating is
917 // needed because the map is never in new space. 917 // needed because the map is never in new space.
918 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), 918 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset),
919 Immediate(Handle<Map>(transition))); 919 Immediate(Handle<Map>(transition)));
920 } 920 }
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 JSFunction* function, 1216 JSFunction* function,
1217 String* name, 1217 String* name,
1218 CheckType check) { 1218 CheckType check) {
1219 // ----------- S t a t e ------------- 1219 // ----------- S t a t e -------------
1220 // -- ecx : name 1220 // -- ecx : name
1221 // -- esp[0] : return address 1221 // -- esp[0] : return address
1222 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1222 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1223 // -- ... 1223 // -- ...
1224 // -- esp[(argc + 1) * 4] : receiver 1224 // -- esp[(argc + 1) * 4] : receiver
1225 // ----------------------------------- 1225 // -----------------------------------
1226 Label miss; 1226 Label miss_in_smi_check;
1227 1227
1228 // Get the receiver from the stack. 1228 // Get the receiver from the stack.
1229 const int argc = arguments().immediate(); 1229 const int argc = arguments().immediate();
1230 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1230 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1231 1231
1232 // Check that the receiver isn't a smi. 1232 // Check that the receiver isn't a smi.
1233 if (check != NUMBER_CHECK) { 1233 if (check != NUMBER_CHECK) {
1234 __ test(edx, Immediate(kSmiTagMask)); 1234 __ test(edx, Immediate(kSmiTagMask));
1235 __ j(zero, &miss, not_taken); 1235 __ j(zero, &miss_in_smi_check, not_taken);
1236 } 1236 }
1237 1237
1238 // Make sure that it's okay not to patch the on stack receiver 1238 // Make sure that it's okay not to patch the on stack receiver
1239 // unless we're doing a receiver map check. 1239 // unless we're doing a receiver map check.
1240 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 1240 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
1241 1241
1242 CallOptimization optimization(function); 1242 CallOptimization optimization(function);
1243 int depth = kInvalidProtoDepth; 1243 int depth = kInvalidProtoDepth;
1244 Label miss;
1244 1245
1245 switch (check) { 1246 switch (check) {
1246 case RECEIVER_MAP_CHECK: 1247 case RECEIVER_MAP_CHECK:
1247 __ IncrementCounter(&Counters::call_const, 1); 1248 __ IncrementCounter(&Counters::call_const, 1);
1248 1249
1249 if (optimization.is_simple_api_call() && !object->IsGlobalObject()) { 1250 if (optimization.is_simple_api_call() && !object->IsGlobalObject()) {
1250 depth = optimization.GetPrototypeDepthOfExpectedType( 1251 depth = optimization.GetPrototypeDepthOfExpectedType(
1251 JSObject::cast(object), holder); 1252 JSObject::cast(object), holder);
1252 } 1253 }
1253 1254
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 GenerateFastApiCall(masm(), optimization, argc); 1353 GenerateFastApiCall(masm(), optimization, argc);
1353 } else { 1354 } else {
1354 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); 1355 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
1355 } 1356 }
1356 1357
1357 // Handle call cache miss. 1358 // Handle call cache miss.
1358 __ bind(&miss); 1359 __ bind(&miss);
1359 if (depth != kInvalidProtoDepth) { 1360 if (depth != kInvalidProtoDepth) {
1360 FreeSpaceForFastApiCall(masm(), eax); 1361 FreeSpaceForFastApiCall(masm(), eax);
1361 } 1362 }
1363 __ bind(&miss_in_smi_check);
1362 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); 1364 Handle<Code> ic = ComputeCallMiss(arguments().immediate());
1363 __ jmp(ic, RelocInfo::CODE_TARGET); 1365 __ jmp(ic, RelocInfo::CODE_TARGET);
1364 1366
1365 // Return the generated code. 1367 // Return the generated code.
1366 String* function_name = NULL; 1368 String* function_name = NULL;
1367 if (function->shared()->name()->IsString()) { 1369 if (function->shared()->name()->IsString()) {
1368 function_name = String::cast(function->shared()->name()); 1370 function_name = String::cast(function->shared()->name());
1369 } 1371 }
1370 return GetCode(CONSTANT_FUNCTION, function_name); 1372 return GetCode(CONSTANT_FUNCTION, function_name);
1371 } 1373 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1580 __ pop(ebx); // remove the return address 1582 __ pop(ebx); // remove the return address
1581 __ push(edx); // receiver 1583 __ push(edx); // receiver
1582 __ push(Immediate(Handle<AccessorInfo>(callback))); // callback info 1584 __ push(Immediate(Handle<AccessorInfo>(callback))); // callback info
1583 __ push(ecx); // name 1585 __ push(ecx); // name
1584 __ push(eax); // value 1586 __ push(eax); // value
1585 __ push(ebx); // restore return address 1587 __ push(ebx); // restore return address
1586 1588
1587 // Do tail-call to the runtime system. 1589 // Do tail-call to the runtime system.
1588 ExternalReference store_callback_property = 1590 ExternalReference store_callback_property =
1589 ExternalReference(IC_Utility(IC::kStoreCallbackProperty)); 1591 ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
1590 __ TailCallRuntime(store_callback_property, 4, 1); 1592 __ TailCallExternalReference(store_callback_property, 4, 1);
1591 1593
1592 // Handle store cache miss. 1594 // Handle store cache miss.
1593 __ bind(&miss); 1595 __ bind(&miss);
1594 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 1596 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
1595 __ jmp(ic, RelocInfo::CODE_TARGET); 1597 __ jmp(ic, RelocInfo::CODE_TARGET);
1596 1598
1597 // Return the generated code. 1599 // Return the generated code.
1598 return GetCode(CALLBACKS, name); 1600 return GetCode(CALLBACKS, name);
1599 } 1601 }
1600 1602
(...skipping 28 matching lines...) Expand all
1629 1631
1630 __ pop(ebx); // remove the return address 1632 __ pop(ebx); // remove the return address
1631 __ push(edx); // receiver 1633 __ push(edx); // receiver
1632 __ push(ecx); // name 1634 __ push(ecx); // name
1633 __ push(eax); // value 1635 __ push(eax); // value
1634 __ push(ebx); // restore return address 1636 __ push(ebx); // restore return address
1635 1637
1636 // Do tail-call to the runtime system. 1638 // Do tail-call to the runtime system.
1637 ExternalReference store_ic_property = 1639 ExternalReference store_ic_property =
1638 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty)); 1640 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
1639 __ TailCallRuntime(store_ic_property, 3, 1); 1641 __ TailCallExternalReference(store_ic_property, 3, 1);
1640 1642
1641 // Handle store cache miss. 1643 // Handle store cache miss.
1642 __ bind(&miss); 1644 __ bind(&miss);
1643 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); 1645 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
1644 __ jmp(ic, RelocInfo::CODE_TARGET); 1646 __ jmp(ic, RelocInfo::CODE_TARGET);
1645 1647
1646 // Return the generated code. 1648 // Return the generated code.
1647 return GetCode(INTERCEPTOR, name); 1649 return GetCode(INTERCEPTOR, name);
1648 } 1650 }
1649 1651
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 return GetCode(NORMAL, name); 1684 return GetCode(NORMAL, name);
1683 } 1685 }
1684 1686
1685 1687
1686 Object* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 1688 Object* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
1687 int index, 1689 int index,
1688 Map* transition, 1690 Map* transition,
1689 String* name) { 1691 String* name) {
1690 // ----------- S t a t e ------------- 1692 // ----------- S t a t e -------------
1691 // -- eax : value 1693 // -- eax : value
1694 // -- ecx : key
1695 // -- edx : receiver
1692 // -- esp[0] : return address 1696 // -- esp[0] : return address
1693 // -- esp[4] : key
1694 // -- esp[8] : receiver
1695 // ----------------------------------- 1697 // -----------------------------------
1696 Label miss; 1698 Label miss;
1697 1699
1698 __ IncrementCounter(&Counters::keyed_store_field, 1); 1700 __ IncrementCounter(&Counters::keyed_store_field, 1);
1699 1701
1700 // Get the name from the stack.
1701 __ mov(ecx, Operand(esp, 1 * kPointerSize));
1702 // Check that the name has not changed. 1702 // Check that the name has not changed.
1703 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); 1703 __ cmp(Operand(ecx), Immediate(Handle<String>(name)));
1704 __ j(not_equal, &miss, not_taken); 1704 __ j(not_equal, &miss, not_taken);
1705 1705
1706 // Get the object from the stack.
1707 __ mov(edx, Operand(esp, 2 * kPointerSize));
1708
1709 // Generate store field code. Trashes the name register. 1706 // Generate store field code. Trashes the name register.
1710 GenerateStoreField(masm(), 1707 GenerateStoreField(masm(),
1711 object, 1708 object,
1712 index, 1709 index,
1713 transition, 1710 transition,
1714 edx, ecx, ebx, 1711 edx, ecx, ebx,
1715 &miss); 1712 &miss);
1716 1713
1717 // Handle store cache miss. 1714 // Handle store cache miss.
1718 __ bind(&miss); 1715 __ bind(&miss);
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
2202 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 2199 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
2203 2200
2204 // Return the generated code. 2201 // Return the generated code.
2205 return GetCode(); 2202 return GetCode();
2206 } 2203 }
2207 2204
2208 2205
2209 #undef __ 2206 #undef __
2210 2207
2211 } } // namespace v8::internal 2208 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/register-allocator-ia32.cc ('k') | src/ia32/virtual-frame-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698