OLD | NEW |
---|---|
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 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
393 } | 393 } |
394 | 394 |
395 | 395 |
396 static void PushInterceptorArguments(MacroAssembler* masm, | 396 static void PushInterceptorArguments(MacroAssembler* masm, |
397 Register receiver, | 397 Register receiver, |
398 Register holder, | 398 Register holder, |
399 Register name, | 399 Register name, |
400 JSObject* holder_obj) { | 400 JSObject* holder_obj) { |
401 __ push(name); | 401 __ push(name); |
402 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); | 402 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); |
403 ASSERT(!HEAP->InNewSpace(interceptor)); | 403 ASSERT(!masm->isolate()->heap()->InNewSpace(interceptor)); |
404 Register scratch = name; | 404 Register scratch = name; |
405 __ mov(scratch, Immediate(Handle<Object>(interceptor))); | 405 __ mov(scratch, Immediate(Handle<Object>(interceptor))); |
406 __ push(scratch); | 406 __ push(scratch); |
407 __ push(receiver); | 407 __ push(receiver); |
408 __ push(holder); | 408 __ push(holder); |
409 __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset)); | 409 __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset)); |
410 } | 410 } |
411 | 411 |
412 | 412 |
413 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, | 413 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
479 // ----------------------------------- | 479 // ----------------------------------- |
480 // Get the function and setup the context. | 480 // Get the function and setup the context. |
481 JSFunction* function = optimization.constant_function(); | 481 JSFunction* function = optimization.constant_function(); |
482 __ mov(edi, Immediate(Handle<JSFunction>(function))); | 482 __ mov(edi, Immediate(Handle<JSFunction>(function))); |
483 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 483 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
484 | 484 |
485 // Pass the additional arguments. | 485 // Pass the additional arguments. |
486 __ mov(Operand(esp, 2 * kPointerSize), edi); | 486 __ mov(Operand(esp, 2 * kPointerSize), edi); |
487 Object* call_data = optimization.api_call_info()->data(); | 487 Object* call_data = optimization.api_call_info()->data(); |
488 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); | 488 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); |
489 if (HEAP->InNewSpace(call_data)) { | 489 if (masm->isolate()->heap()->InNewSpace(call_data)) { |
490 __ mov(ecx, api_call_info_handle); | 490 __ mov(ecx, api_call_info_handle); |
491 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); | 491 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); |
492 __ mov(Operand(esp, 3 * kPointerSize), ebx); | 492 __ mov(Operand(esp, 3 * kPointerSize), ebx); |
493 } else { | 493 } else { |
494 __ mov(Operand(esp, 3 * kPointerSize), | 494 __ mov(Operand(esp, 3 * kPointerSize), |
495 Immediate(Handle<Object>(call_data))); | 495 Immediate(Handle<Object>(call_data))); |
496 } | 496 } |
497 | 497 |
498 // Prepare arguments. | 498 // Prepare arguments. |
499 __ lea(eax, Operand(esp, 3 * kPointerSize)); | 499 __ lea(eax, Operand(esp, 3 * kPointerSize)); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
573 } else { | 573 } else { |
574 CompileRegular(masm, | 574 CompileRegular(masm, |
575 object, | 575 object, |
576 receiver, | 576 receiver, |
577 scratch1, | 577 scratch1, |
578 scratch2, | 578 scratch2, |
579 scratch3, | 579 scratch3, |
580 name, | 580 name, |
581 holder, | 581 holder, |
582 miss); | 582 miss); |
583 return HEAP->undefined_value(); // Success. | 583 return masm->isolate()->heap()->undefined_value(); // Success. |
584 } | 584 } |
585 } | 585 } |
586 | 586 |
587 private: | 587 private: |
588 MaybeObject* CompileCacheable(MacroAssembler* masm, | 588 MaybeObject* CompileCacheable(MacroAssembler* masm, |
589 JSObject* object, | 589 JSObject* object, |
590 Register receiver, | 590 Register receiver, |
591 Register scratch1, | 591 Register scratch1, |
592 Register scratch2, | 592 Register scratch2, |
593 Register scratch3, | 593 Register scratch3, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
672 FreeSpaceForFastApiCall(masm, scratch1); | 672 FreeSpaceForFastApiCall(masm, scratch1); |
673 __ jmp(miss_label); | 673 __ jmp(miss_label); |
674 } | 674 } |
675 | 675 |
676 // Invoke a regular function. | 676 // Invoke a regular function. |
677 __ bind(®ular_invoke); | 677 __ bind(®ular_invoke); |
678 if (can_do_fast_api_call) { | 678 if (can_do_fast_api_call) { |
679 FreeSpaceForFastApiCall(masm, scratch1); | 679 FreeSpaceForFastApiCall(masm, scratch1); |
680 } | 680 } |
681 | 681 |
682 return HEAP->undefined_value(); // Success. | 682 return masm->isolate()->heap()->undefined_value(); // Success. |
683 } | 683 } |
684 | 684 |
685 void CompileRegular(MacroAssembler* masm, | 685 void CompileRegular(MacroAssembler* masm, |
686 JSObject* object, | 686 JSObject* object, |
687 Register receiver, | 687 Register receiver, |
688 Register scratch1, | 688 Register scratch1, |
689 Register scratch2, | 689 Register scratch2, |
690 Register scratch3, | 690 Register scratch3, |
691 String* name, | 691 String* name, |
692 JSObject* interceptor_holder, | 692 JSObject* interceptor_holder, |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
909 Register holder_reg, | 909 Register holder_reg, |
910 Register scratch1, | 910 Register scratch1, |
911 Register scratch2, | 911 Register scratch2, |
912 String* name, | 912 String* name, |
913 int save_at_depth, | 913 int save_at_depth, |
914 Label* miss) { | 914 Label* miss) { |
915 // Make sure there's no overlap between holder and object registers. | 915 // Make sure there's no overlap between holder and object registers. |
916 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 916 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
917 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 917 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
918 && !scratch2.is(scratch1)); | 918 && !scratch2.is(scratch1)); |
919 | |
920 Heap* heap = masm()->isolate()->heap(); | |
Vitaly Repeshko
2011/03/25 12:57:51
There's StubCompiler::isolate() that we could use
Mads Ager (chromium)
2011/03/25 13:09:26
Great! Replaced a lot of occurences of masm->isola
| |
921 | |
919 // Keep track of the current object in register reg. | 922 // Keep track of the current object in register reg. |
920 Register reg = object_reg; | 923 Register reg = object_reg; |
921 JSObject* current = object; | 924 JSObject* current = object; |
922 int depth = 0; | 925 int depth = 0; |
923 | 926 |
924 if (save_at_depth == depth) { | 927 if (save_at_depth == depth) { |
925 __ mov(Operand(esp, kPointerSize), reg); | 928 __ mov(Operand(esp, kPointerSize), reg); |
926 } | 929 } |
927 | 930 |
928 // Traverse the prototype chain and check the maps in the prototype chain for | 931 // Traverse the prototype chain and check the maps in the prototype chain for |
929 // fast and global objects or do negative lookup for normal objects. | 932 // fast and global objects or do negative lookup for normal objects. |
930 while (current != holder) { | 933 while (current != holder) { |
931 depth++; | 934 depth++; |
932 | 935 |
933 // Only global objects and objects that do not require access | 936 // Only global objects and objects that do not require access |
934 // checks are allowed in stubs. | 937 // checks are allowed in stubs. |
935 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 938 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
936 | 939 |
937 ASSERT(current->GetPrototype()->IsJSObject()); | 940 ASSERT(current->GetPrototype()->IsJSObject()); |
938 JSObject* prototype = JSObject::cast(current->GetPrototype()); | 941 JSObject* prototype = JSObject::cast(current->GetPrototype()); |
939 if (!current->HasFastProperties() && | 942 if (!current->HasFastProperties() && |
940 !current->IsJSGlobalObject() && | 943 !current->IsJSGlobalObject() && |
941 !current->IsJSGlobalProxy()) { | 944 !current->IsJSGlobalProxy()) { |
942 if (!name->IsSymbol()) { | 945 if (!name->IsSymbol()) { |
943 MaybeObject* maybe_lookup_result = HEAP->LookupSymbol(name); | 946 MaybeObject* maybe_lookup_result = heap->LookupSymbol(name); |
944 Object* lookup_result = NULL; // Initialization to please compiler. | 947 Object* lookup_result = NULL; // Initialization to please compiler. |
945 if (!maybe_lookup_result->ToObject(&lookup_result)) { | 948 if (!maybe_lookup_result->ToObject(&lookup_result)) { |
946 set_failure(Failure::cast(maybe_lookup_result)); | 949 set_failure(Failure::cast(maybe_lookup_result)); |
947 return reg; | 950 return reg; |
948 } | 951 } |
949 name = String::cast(lookup_result); | 952 name = String::cast(lookup_result); |
950 } | 953 } |
951 ASSERT(current->property_dictionary()->FindEntry(name) == | 954 ASSERT(current->property_dictionary()->FindEntry(name) == |
952 StringDictionary::kNotFound); | 955 StringDictionary::kNotFound); |
953 | 956 |
954 GenerateDictionaryNegativeLookup(masm(), | 957 GenerateDictionaryNegativeLookup(masm(), |
955 miss, | 958 miss, |
956 reg, | 959 reg, |
957 name, | 960 name, |
958 scratch1, | 961 scratch1, |
959 scratch2); | 962 scratch2); |
960 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 963 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
961 reg = holder_reg; // from now the object is in holder_reg | 964 reg = holder_reg; // from now the object is in holder_reg |
962 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 965 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
963 } else if (HEAP->InNewSpace(prototype)) { | 966 } else if (heap->InNewSpace(prototype)) { |
964 // Get the map of the current object. | 967 // Get the map of the current object. |
965 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 968 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
966 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map()))); | 969 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map()))); |
967 // Branch on the result of the map check. | 970 // Branch on the result of the map check. |
968 __ j(not_equal, miss, not_taken); | 971 __ j(not_equal, miss, not_taken); |
969 // Check access rights to the global object. This has to happen | 972 // Check access rights to the global object. This has to happen |
970 // after the map check so that we know that the object is | 973 // after the map check so that we know that the object is |
971 // actually a global object. | 974 // actually a global object. |
972 if (current->IsJSGlobalProxy()) { | 975 if (current->IsJSGlobalProxy()) { |
973 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 976 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1083 | 1086 |
1084 // Insert additional parameters into the stack frame above return address. | 1087 // Insert additional parameters into the stack frame above return address. |
1085 ASSERT(!scratch3.is(reg)); | 1088 ASSERT(!scratch3.is(reg)); |
1086 __ pop(scratch3); // Get return address to place it below. | 1089 __ pop(scratch3); // Get return address to place it below. |
1087 | 1090 |
1088 __ push(receiver); // receiver | 1091 __ push(receiver); // receiver |
1089 __ mov(scratch2, Operand(esp)); | 1092 __ mov(scratch2, Operand(esp)); |
1090 ASSERT(!scratch2.is(reg)); | 1093 ASSERT(!scratch2.is(reg)); |
1091 __ push(reg); // holder | 1094 __ push(reg); // holder |
1092 // Push data from AccessorInfo. | 1095 // Push data from AccessorInfo. |
1093 if (HEAP->InNewSpace(callback_handle->data())) { | 1096 if (masm()->isolate()->heap()->InNewSpace(callback_handle->data())) { |
1094 __ mov(scratch1, Immediate(callback_handle)); | 1097 __ mov(scratch1, Immediate(callback_handle)); |
1095 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); | 1098 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); |
1096 } else { | 1099 } else { |
1097 __ push(Immediate(Handle<Object>(callback_handle->data()))); | 1100 __ push(Immediate(Handle<Object>(callback_handle->data()))); |
1098 } | 1101 } |
1099 | 1102 |
1100 // Save a pointer to where we pushed the arguments pointer. | 1103 // Save a pointer to where we pushed the arguments pointer. |
1101 // This will be passed as the const AccessorInfo& to the C++ callback. | 1104 // This will be passed as the const AccessorInfo& to the C++ callback. |
1102 __ push(scratch2); | 1105 __ push(scratch2); |
1103 | 1106 |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1330 Label* miss) { | 1333 Label* miss) { |
1331 // Get the value from the cell. | 1334 // Get the value from the cell. |
1332 if (Serializer::enabled()) { | 1335 if (Serializer::enabled()) { |
1333 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 1336 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
1334 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); | 1337 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); |
1335 } else { | 1338 } else { |
1336 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); | 1339 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); |
1337 } | 1340 } |
1338 | 1341 |
1339 // Check that the cell contains the same function. | 1342 // Check that the cell contains the same function. |
1340 if (HEAP->InNewSpace(function)) { | 1343 if (masm()->isolate()->heap()->InNewSpace(function)) { |
1341 // We can't embed a pointer to a function in new space so we have | 1344 // We can't embed a pointer to a function in new space so we have |
1342 // to verify that the shared function info is unchanged. This has | 1345 // to verify that the shared function info is unchanged. This has |
1343 // the nice side effect that multiple closures based on the same | 1346 // the nice side effect that multiple closures based on the same |
1344 // function can all use this call IC. Before we load through the | 1347 // function can all use this call IC. Before we load through the |
1345 // function, we have to verify that it still is a function. | 1348 // function, we have to verify that it still is a function. |
1346 __ test(edi, Immediate(kSmiTagMask)); | 1349 __ test(edi, Immediate(kSmiTagMask)); |
1347 __ j(zero, miss, not_taken); | 1350 __ j(zero, miss, not_taken); |
1348 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); | 1351 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); |
1349 __ j(not_equal, miss, not_taken); | 1352 __ j(not_equal, miss, not_taken); |
1350 | 1353 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1433 String* name) { | 1436 String* name) { |
1434 // ----------- S t a t e ------------- | 1437 // ----------- S t a t e ------------- |
1435 // -- ecx : name | 1438 // -- ecx : name |
1436 // -- esp[0] : return address | 1439 // -- esp[0] : return address |
1437 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1440 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1438 // -- ... | 1441 // -- ... |
1439 // -- esp[(argc + 1) * 4] : receiver | 1442 // -- esp[(argc + 1) * 4] : receiver |
1440 // ----------------------------------- | 1443 // ----------------------------------- |
1441 | 1444 |
1442 // If object is not an array, bail out to regular call. | 1445 // If object is not an array, bail out to regular call. |
1443 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value(); | 1446 if (!object->IsJSArray() || cell != NULL) { |
1447 return masm()->isolate()->heap()->undefined_value(); | |
1448 } | |
1444 | 1449 |
1445 Label miss; | 1450 Label miss; |
1446 | 1451 |
1447 GenerateNameCheck(name, &miss); | 1452 GenerateNameCheck(name, &miss); |
1448 | 1453 |
1449 // Get the receiver from the stack. | 1454 // Get the receiver from the stack. |
1450 const int argc = arguments().immediate(); | 1455 const int argc = arguments().immediate(); |
1451 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1456 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1452 | 1457 |
1453 // Check that the receiver isn't a smi. | 1458 // Check that the receiver isn't a smi. |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1585 String* name) { | 1590 String* name) { |
1586 // ----------- S t a t e ------------- | 1591 // ----------- S t a t e ------------- |
1587 // -- ecx : name | 1592 // -- ecx : name |
1588 // -- esp[0] : return address | 1593 // -- esp[0] : return address |
1589 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1594 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1590 // -- ... | 1595 // -- ... |
1591 // -- esp[(argc + 1) * 4] : receiver | 1596 // -- esp[(argc + 1) * 4] : receiver |
1592 // ----------------------------------- | 1597 // ----------------------------------- |
1593 | 1598 |
1594 // If object is not an array, bail out to regular call. | 1599 // If object is not an array, bail out to regular call. |
1595 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value(); | 1600 if (!object->IsJSArray() || cell != NULL) { |
1601 return masm()->isolate()->heap()->undefined_value(); | |
1602 } | |
1596 | 1603 |
1597 Label miss, return_undefined, call_builtin; | 1604 Label miss, return_undefined, call_builtin; |
1598 | 1605 |
1599 GenerateNameCheck(name, &miss); | 1606 GenerateNameCheck(name, &miss); |
1600 | 1607 |
1601 // Get the receiver from the stack. | 1608 // Get the receiver from the stack. |
1602 const int argc = arguments().immediate(); | 1609 const int argc = arguments().immediate(); |
1603 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1610 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1604 | 1611 |
1605 // Check that the receiver isn't a smi. | 1612 // Check that the receiver isn't a smi. |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1752 String* name) { | 1759 String* name) { |
1753 // ----------- S t a t e ------------- | 1760 // ----------- S t a t e ------------- |
1754 // -- ecx : function name | 1761 // -- ecx : function name |
1755 // -- esp[0] : return address | 1762 // -- esp[0] : return address |
1756 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1763 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1757 // -- ... | 1764 // -- ... |
1758 // -- esp[(argc + 1) * 4] : receiver | 1765 // -- esp[(argc + 1) * 4] : receiver |
1759 // ----------------------------------- | 1766 // ----------------------------------- |
1760 | 1767 |
1761 // If object is not a string, bail out to regular call. | 1768 // If object is not a string, bail out to regular call. |
1762 if (!object->IsString() || cell != NULL) return HEAP->undefined_value(); | 1769 if (!object->IsString() || cell != NULL) { |
1770 return masm()->isolate()->heap()->undefined_value(); | |
1771 } | |
1763 | 1772 |
1764 const int argc = arguments().immediate(); | 1773 const int argc = arguments().immediate(); |
1765 | 1774 |
1766 Label miss; | 1775 Label miss; |
1767 Label name_miss; | 1776 Label name_miss; |
1768 Label index_out_of_range; | 1777 Label index_out_of_range; |
1769 Label* index_out_of_range_label = &index_out_of_range; | 1778 Label* index_out_of_range_label = &index_out_of_range; |
1770 | 1779 |
1771 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { | 1780 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { |
1772 index_out_of_range_label = &miss; | 1781 index_out_of_range_label = &miss; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1839 // -- esp[0] : return address | 1848 // -- esp[0] : return address |
1840 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1849 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1841 // -- ... | 1850 // -- ... |
1842 // -- esp[(argc + 1) * 4] : receiver | 1851 // -- esp[(argc + 1) * 4] : receiver |
1843 // ----------------------------------- | 1852 // ----------------------------------- |
1844 | 1853 |
1845 const int argc = arguments().immediate(); | 1854 const int argc = arguments().immediate(); |
1846 | 1855 |
1847 // If the object is not a JSObject or we got an unexpected number of | 1856 // If the object is not a JSObject or we got an unexpected number of |
1848 // arguments, bail out to the regular call. | 1857 // arguments, bail out to the regular call. |
1849 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); | 1858 if (!object->IsJSObject() || argc != 1) { |
1859 return masm()->isolate()->heap()->undefined_value(); | |
1860 } | |
1850 | 1861 |
1851 Label miss; | 1862 Label miss; |
1852 GenerateNameCheck(name, &miss); | 1863 GenerateNameCheck(name, &miss); |
1853 | 1864 |
1854 if (cell == NULL) { | 1865 if (cell == NULL) { |
1855 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 1866 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
1856 | 1867 |
1857 STATIC_ASSERT(kSmiTag == 0); | 1868 STATIC_ASSERT(kSmiTag == 0); |
1858 __ test(edx, Immediate(kSmiTagMask)); | 1869 __ test(edx, Immediate(kSmiTagMask)); |
1859 __ j(zero, &miss); | 1870 __ j(zero, &miss); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1907 JSFunction* function, | 1918 JSFunction* function, |
1908 String* name) { | 1919 String* name) { |
1909 // ----------- S t a t e ------------- | 1920 // ----------- S t a t e ------------- |
1910 // -- ecx : name | 1921 // -- ecx : name |
1911 // -- esp[0] : return address | 1922 // -- esp[0] : return address |
1912 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1923 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1913 // -- ... | 1924 // -- ... |
1914 // -- esp[(argc + 1) * 4] : receiver | 1925 // -- esp[(argc + 1) * 4] : receiver |
1915 // ----------------------------------- | 1926 // ----------------------------------- |
1916 | 1927 |
1917 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) | 1928 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) { |
1918 return HEAP->undefined_value(); | 1929 return masm()->isolate()->heap()->undefined_value(); |
1930 } | |
1931 | |
1919 CpuFeatures::Scope use_sse2(SSE2); | 1932 CpuFeatures::Scope use_sse2(SSE2); |
1920 | 1933 |
1921 const int argc = arguments().immediate(); | 1934 const int argc = arguments().immediate(); |
1922 | 1935 |
1923 // If the object is not a JSObject or we got an unexpected number of | 1936 // If the object is not a JSObject or we got an unexpected number of |
1924 // arguments, bail out to the regular call. | 1937 // arguments, bail out to the regular call. |
1925 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); | 1938 if (!object->IsJSObject() || argc != 1) { |
1939 return masm()->isolate()->heap()->undefined_value(); | |
1940 } | |
1926 | 1941 |
1927 Label miss; | 1942 Label miss; |
1928 GenerateNameCheck(name, &miss); | 1943 GenerateNameCheck(name, &miss); |
1929 | 1944 |
1930 if (cell == NULL) { | 1945 if (cell == NULL) { |
1931 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 1946 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
1932 | 1947 |
1933 STATIC_ASSERT(kSmiTag == 0); | 1948 STATIC_ASSERT(kSmiTag == 0); |
1934 __ test(edx, Immediate(kSmiTagMask)); | 1949 __ test(edx, Immediate(kSmiTagMask)); |
1935 __ j(zero, &miss); | 1950 __ j(zero, &miss); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2037 // -- esp[0] : return address | 2052 // -- esp[0] : return address |
2038 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2053 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
2039 // -- ... | 2054 // -- ... |
2040 // -- esp[(argc + 1) * 4] : receiver | 2055 // -- esp[(argc + 1) * 4] : receiver |
2041 // ----------------------------------- | 2056 // ----------------------------------- |
2042 | 2057 |
2043 const int argc = arguments().immediate(); | 2058 const int argc = arguments().immediate(); |
2044 | 2059 |
2045 // If the object is not a JSObject or we got an unexpected number of | 2060 // If the object is not a JSObject or we got an unexpected number of |
2046 // arguments, bail out to the regular call. | 2061 // arguments, bail out to the regular call. |
2047 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); | 2062 if (!object->IsJSObject() || argc != 1) { |
2063 return masm()->isolate()->heap()->undefined_value(); | |
2064 } | |
2048 | 2065 |
2049 Label miss; | 2066 Label miss; |
2050 GenerateNameCheck(name, &miss); | 2067 GenerateNameCheck(name, &miss); |
2051 | 2068 |
2052 if (cell == NULL) { | 2069 if (cell == NULL) { |
2053 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 2070 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
2054 | 2071 |
2055 STATIC_ASSERT(kSmiTag == 0); | 2072 STATIC_ASSERT(kSmiTag == 0); |
2056 __ test(edx, Immediate(kSmiTagMask)); | 2073 __ test(edx, Immediate(kSmiTagMask)); |
2057 __ j(zero, &miss); | 2074 __ j(zero, &miss); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2133 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2150 MaybeObject* CallStubCompiler::CompileFastApiCall( |
2134 const CallOptimization& optimization, | 2151 const CallOptimization& optimization, |
2135 Object* object, | 2152 Object* object, |
2136 JSObject* holder, | 2153 JSObject* holder, |
2137 JSGlobalPropertyCell* cell, | 2154 JSGlobalPropertyCell* cell, |
2138 JSFunction* function, | 2155 JSFunction* function, |
2139 String* name) { | 2156 String* name) { |
2140 ASSERT(optimization.is_simple_api_call()); | 2157 ASSERT(optimization.is_simple_api_call()); |
2141 // Bail out if object is a global object as we don't want to | 2158 // Bail out if object is a global object as we don't want to |
2142 // repatch it to global receiver. | 2159 // repatch it to global receiver. |
2143 if (object->IsGlobalObject()) return HEAP->undefined_value(); | 2160 Heap* heap = masm()->isolate()->heap(); |
2144 if (cell != NULL) return HEAP->undefined_value(); | 2161 if (object->IsGlobalObject()) return heap->undefined_value(); |
2162 if (cell != NULL) return heap->undefined_value(); | |
2145 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2163 int depth = optimization.GetPrototypeDepthOfExpectedType( |
2146 JSObject::cast(object), holder); | 2164 JSObject::cast(object), holder); |
2147 if (depth == kInvalidProtoDepth) return HEAP->undefined_value(); | 2165 if (depth == kInvalidProtoDepth) return heap->undefined_value(); |
2148 | 2166 |
2149 Label miss, miss_before_stack_reserved; | 2167 Label miss, miss_before_stack_reserved; |
2150 | 2168 |
2151 GenerateNameCheck(name, &miss_before_stack_reserved); | 2169 GenerateNameCheck(name, &miss_before_stack_reserved); |
2152 | 2170 |
2153 // Get the receiver from the stack. | 2171 // Get the receiver from the stack. |
2154 const int argc = arguments().immediate(); | 2172 const int argc = arguments().immediate(); |
2155 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2173 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
2156 | 2174 |
2157 // Check that the receiver isn't a smi. | 2175 // Check that the receiver isn't a smi. |
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2743 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2761 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, |
2744 JSObject* object, | 2762 JSObject* object, |
2745 JSObject* last) { | 2763 JSObject* last) { |
2746 // ----------- S t a t e ------------- | 2764 // ----------- S t a t e ------------- |
2747 // -- eax : receiver | 2765 // -- eax : receiver |
2748 // -- ecx : name | 2766 // -- ecx : name |
2749 // -- esp[0] : return address | 2767 // -- esp[0] : return address |
2750 // ----------------------------------- | 2768 // ----------------------------------- |
2751 Label miss; | 2769 Label miss; |
2752 | 2770 |
2771 Isolate* isolate = masm()->isolate(); | |
2772 | |
2753 // Check that the receiver isn't a smi. | 2773 // Check that the receiver isn't a smi. |
2754 __ test(eax, Immediate(kSmiTagMask)); | 2774 __ test(eax, Immediate(kSmiTagMask)); |
2755 __ j(zero, &miss, not_taken); | 2775 __ j(zero, &miss, not_taken); |
2756 | 2776 |
2757 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); | 2777 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); |
2758 | 2778 |
2759 // Check the maps of the full prototype chain. Also check that | 2779 // Check the maps of the full prototype chain. Also check that |
2760 // global property cells up to (but not including) the last object | 2780 // global property cells up to (but not including) the last object |
2761 // in the prototype chain are empty. | 2781 // in the prototype chain are empty. |
2762 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); | 2782 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); |
2763 | 2783 |
2764 // If the last object in the prototype chain is a global object, | 2784 // If the last object in the prototype chain is a global object, |
2765 // check that the global property cell is empty. | 2785 // check that the global property cell is empty. |
2766 if (last->IsGlobalObject()) { | 2786 if (last->IsGlobalObject()) { |
2767 MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 2787 MaybeObject* cell = GenerateCheckPropertyCell(masm(), |
2768 GlobalObject::cast(last), | 2788 GlobalObject::cast(last), |
2769 name, | 2789 name, |
2770 edx, | 2790 edx, |
2771 &miss); | 2791 &miss); |
2772 if (cell->IsFailure()) { | 2792 if (cell->IsFailure()) { |
2773 miss.Unuse(); | 2793 miss.Unuse(); |
2774 return cell; | 2794 return cell; |
2775 } | 2795 } |
2776 } | 2796 } |
2777 | 2797 |
2778 // Return undefined if maps of the full prototype chain are still the | 2798 // Return undefined if maps of the full prototype chain are still the |
2779 // same and no global property with this name contains a value. | 2799 // same and no global property with this name contains a value. |
2780 __ mov(eax, FACTORY->undefined_value()); | 2800 __ mov(eax, isolate->factory()->undefined_value()); |
2781 __ ret(0); | 2801 __ ret(0); |
2782 | 2802 |
2783 __ bind(&miss); | 2803 __ bind(&miss); |
2784 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2804 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2785 | 2805 |
2786 // Return the generated code. | 2806 // Return the generated code. |
2787 return GetCode(NONEXISTENT, HEAP->empty_string()); | 2807 return GetCode(NONEXISTENT, isolate->heap()->empty_string()); |
2788 } | 2808 } |
2789 | 2809 |
2790 | 2810 |
2791 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, | 2811 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, |
2792 JSObject* holder, | 2812 JSObject* holder, |
2793 int index, | 2813 int index, |
2794 String* name) { | 2814 String* name) { |
2795 // ----------- S t a t e ------------- | 2815 // ----------- S t a t e ------------- |
2796 // -- eax : receiver | 2816 // -- eax : receiver |
2797 // -- ecx : name | 2817 // -- ecx : name |
(...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3690 | 3710 |
3691 return GetCode(flags); | 3711 return GetCode(flags); |
3692 } | 3712 } |
3693 | 3713 |
3694 | 3714 |
3695 #undef __ | 3715 #undef __ |
3696 | 3716 |
3697 } } // namespace v8::internal | 3717 } } // namespace v8::internal |
3698 | 3718 |
3699 #endif // V8_TARGET_ARCH_IA32 | 3719 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |