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 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 } | 800 } |
801 | 801 |
802 // Return the value (register eax). | 802 // Return the value (register eax). |
803 __ ret(0); | 803 __ ret(0); |
804 } | 804 } |
805 | 805 |
806 | 806 |
807 // Generate code to check that a global property cell is empty. Create | 807 // Generate code to check that a global property cell is empty. Create |
808 // the property cell at compilation time if no cell exists for the | 808 // the property cell at compilation time if no cell exists for the |
809 // property. | 809 // property. |
810 static Object* GenerateCheckPropertyCell(MacroAssembler* masm, | 810 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( |
811 GlobalObject* global, | 811 MacroAssembler* masm, |
812 String* name, | 812 GlobalObject* global, |
813 Register scratch, | 813 String* name, |
814 Label* miss) { | 814 Register scratch, |
815 Object* probe = global->EnsurePropertyCell(name); | 815 Label* miss) { |
816 if (probe->IsFailure()) return probe; | 816 Object* probe; |
| 817 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); |
| 818 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
| 819 } |
817 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 820 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
818 ASSERT(cell->value()->IsTheHole()); | 821 ASSERT(cell->value()->IsTheHole()); |
819 __ mov(scratch, Immediate(Handle<Object>(cell))); | 822 __ mov(scratch, Immediate(Handle<Object>(cell))); |
820 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 823 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
821 Immediate(Factory::the_hole_value())); | 824 Immediate(Factory::the_hole_value())); |
822 __ j(not_equal, miss, not_taken); | 825 __ j(not_equal, miss, not_taken); |
823 return cell; | 826 return cell; |
824 } | 827 } |
825 | 828 |
826 | 829 |
827 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 830 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
828 // from object to (but not including) holder. | 831 // from object to (but not including) holder. |
829 static Object* GenerateCheckPropertyCells(MacroAssembler* masm, | 832 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( |
830 JSObject* object, | 833 MacroAssembler* masm, |
831 JSObject* holder, | 834 JSObject* object, |
832 String* name, | 835 JSObject* holder, |
833 Register scratch, | 836 String* name, |
834 Label* miss) { | 837 Register scratch, |
| 838 Label* miss) { |
835 JSObject* current = object; | 839 JSObject* current = object; |
836 while (current != holder) { | 840 while (current != holder) { |
837 if (current->IsGlobalObject()) { | 841 if (current->IsGlobalObject()) { |
838 Object* cell = GenerateCheckPropertyCell(masm, | 842 // Returns a cell or a failure. |
839 GlobalObject::cast(current), | 843 MaybeObject* result = GenerateCheckPropertyCell( |
840 name, | 844 masm, |
841 scratch, | 845 GlobalObject::cast(current), |
842 miss); | 846 name, |
843 if (cell->IsFailure()) { | 847 scratch, |
844 return cell; | 848 miss); |
845 } | 849 if (result->IsFailure()) return result; |
846 } | 850 } |
847 ASSERT(current->IsJSObject()); | 851 ASSERT(current->IsJSObject()); |
848 current = JSObject::cast(current->GetPrototype()); | 852 current = JSObject::cast(current->GetPrototype()); |
849 } | 853 } |
850 return NULL; | 854 return NULL; |
851 } | 855 } |
852 | 856 |
853 | 857 |
854 #undef __ | 858 #undef __ |
855 #define __ ACCESS_MASM(masm()) | 859 #define __ ACCESS_MASM(masm()) |
(...skipping 29 matching lines...) Expand all Loading... |
885 // Only global objects and objects that do not require access | 889 // Only global objects and objects that do not require access |
886 // checks are allowed in stubs. | 890 // checks are allowed in stubs. |
887 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 891 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
888 | 892 |
889 ASSERT(current->GetPrototype()->IsJSObject()); | 893 ASSERT(current->GetPrototype()->IsJSObject()); |
890 JSObject* prototype = JSObject::cast(current->GetPrototype()); | 894 JSObject* prototype = JSObject::cast(current->GetPrototype()); |
891 if (!current->HasFastProperties() && | 895 if (!current->HasFastProperties() && |
892 !current->IsJSGlobalObject() && | 896 !current->IsJSGlobalObject() && |
893 !current->IsJSGlobalProxy()) { | 897 !current->IsJSGlobalProxy()) { |
894 if (!name->IsSymbol()) { | 898 if (!name->IsSymbol()) { |
895 Object* lookup_result = Heap::LookupSymbol(name); | 899 MaybeObject* maybe_lookup_result = Heap::LookupSymbol(name); |
896 if (lookup_result->IsFailure()) { | 900 Object* lookup_result = NULL; // Initialization to please compiler. |
| 901 if (!maybe_lookup_result->ToObject(&lookup_result)) { |
897 set_failure(Failure::cast(lookup_result)); | 902 set_failure(Failure::cast(lookup_result)); |
898 return reg; | 903 return reg; |
899 } else { | |
900 name = String::cast(lookup_result); | |
901 } | 904 } |
| 905 name = String::cast(lookup_result); |
902 } | 906 } |
903 ASSERT(current->property_dictionary()->FindEntry(name) == | 907 ASSERT(current->property_dictionary()->FindEntry(name) == |
904 StringDictionary::kNotFound); | 908 StringDictionary::kNotFound); |
905 | 909 |
906 GenerateDictionaryNegativeLookup(masm(), | 910 GenerateDictionaryNegativeLookup(masm(), |
907 miss, | 911 miss, |
908 reg, | 912 reg, |
909 name, | 913 name, |
910 scratch1, | 914 scratch1, |
911 scratch2); | 915 scratch2); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 | 972 |
969 // Perform security check for access to the global object. | 973 // Perform security check for access to the global object. |
970 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 974 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
971 if (holder->IsJSGlobalProxy()) { | 975 if (holder->IsJSGlobalProxy()) { |
972 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 976 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
973 }; | 977 }; |
974 | 978 |
975 // If we've skipped any global objects, it's not enough to verify | 979 // If we've skipped any global objects, it's not enough to verify |
976 // that their maps haven't changed. We also need to check that the | 980 // that their maps haven't changed. We also need to check that the |
977 // property cell for the property is still empty. | 981 // property cell for the property is still empty. |
978 Object* result = GenerateCheckPropertyCells(masm(), | 982 MaybeObject* result = GenerateCheckPropertyCells(masm(), |
979 object, | 983 object, |
980 holder, | 984 holder, |
981 name, | 985 name, |
982 scratch1, | 986 scratch1, |
983 miss); | 987 miss); |
984 if (result->IsFailure()) set_failure(Failure::cast(result)); | 988 if (result->IsFailure()) set_failure(Failure::cast(result)); |
985 | 989 |
986 // Return the register containing the holder. | 990 // Return the register containing the holder. |
987 return reg; | 991 return reg; |
988 } | 992 } |
989 | 993 |
990 | 994 |
991 void StubCompiler::GenerateLoadField(JSObject* object, | 995 void StubCompiler::GenerateLoadField(JSObject* object, |
992 JSObject* holder, | 996 JSObject* holder, |
993 Register receiver, | 997 Register receiver, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 __ j(zero, miss, not_taken); | 1032 __ j(zero, miss, not_taken); |
1029 | 1033 |
1030 // Check that the maps haven't changed. | 1034 // Check that the maps haven't changed. |
1031 Register reg = | 1035 Register reg = |
1032 CheckPrototypes(object, receiver, holder, scratch1, | 1036 CheckPrototypes(object, receiver, holder, scratch1, |
1033 scratch2, scratch3, name, miss); | 1037 scratch2, scratch3, name, miss); |
1034 | 1038 |
1035 Handle<AccessorInfo> callback_handle(callback); | 1039 Handle<AccessorInfo> callback_handle(callback); |
1036 | 1040 |
1037 __ EnterInternalFrame(); | 1041 __ EnterInternalFrame(); |
1038 __ PushHandleScope(scratch2); | |
1039 // Push the stack address where the list of arguments ends. | 1042 // Push the stack address where the list of arguments ends. |
1040 __ mov(scratch2, esp); | 1043 __ mov(scratch2, esp); |
1041 __ sub(Operand(scratch2), Immediate(2 * kPointerSize)); | 1044 __ sub(Operand(scratch2), Immediate(2 * kPointerSize)); |
1042 __ push(scratch2); | 1045 __ push(scratch2); |
1043 __ push(receiver); // receiver | 1046 __ push(receiver); // receiver |
1044 __ push(reg); // holder | 1047 __ push(reg); // holder |
1045 // Push data from AccessorInfo. | 1048 // Push data from AccessorInfo. |
1046 if (Heap::InNewSpace(callback_handle->data())) { | 1049 if (Heap::InNewSpace(callback_handle->data())) { |
1047 __ mov(scratch2, Immediate(callback_handle)); | 1050 __ mov(scratch2, Immediate(callback_handle)); |
1048 __ push(FieldOperand(scratch2, AccessorInfo::kDataOffset)); | 1051 __ push(FieldOperand(scratch2, AccessorInfo::kDataOffset)); |
1049 } else { | 1052 } else { |
1050 __ push(Immediate(Handle<Object>(callback_handle->data()))); | 1053 __ push(Immediate(Handle<Object>(callback_handle->data()))); |
1051 } | 1054 } |
1052 __ push(name_reg); // name | 1055 __ push(name_reg); // name |
1053 // Save a pointer to where we pushed the arguments pointer. | 1056 // Save a pointer to where we pushed the arguments pointer. |
1054 // This will be passed as the const AccessorInfo& to the C++ callback. | 1057 // This will be passed as the const AccessorInfo& to the C++ callback. |
1055 __ mov(eax, esp); | 1058 __ mov(eax, esp); |
1056 __ add(Operand(eax), Immediate(4 * kPointerSize)); | 1059 __ add(Operand(eax), Immediate(4 * kPointerSize)); |
1057 __ mov(ebx, esp); | 1060 __ mov(ebx, esp); |
1058 | 1061 |
1059 // Do call through the api. | 1062 // Do call through the api. |
1060 ASSERT_EQ(5, ApiGetterEntryStub::kStackSpace); | 1063 ASSERT_EQ(5, ApiGetterEntryStub::kStackSpace); |
1061 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1064 Address getter_address = v8::ToCData<Address>(callback->getter()); |
1062 ApiFunction fun(getter_address); | 1065 ApiFunction fun(getter_address); |
1063 ApiGetterEntryStub stub(callback_handle, &fun); | 1066 ApiGetterEntryStub stub(callback_handle, &fun); |
1064 // Emitting a stub call may try to allocate (if the code is not | 1067 // Emitting a stub call may try to allocate (if the code is not |
1065 // already generated). Do not allow the assembler to perform a | 1068 // already generated). Do not allow the assembler to perform a |
1066 // garbage collection but instead return the allocation failure | 1069 // garbage collection but instead return the allocation failure |
1067 // object. | 1070 // object. |
1068 Object* result = masm()->TryCallStub(&stub); | 1071 Object* result = NULL; // Initialization to please compiler. |
1069 if (result->IsFailure()) { | 1072 { MaybeObject* try_call_result = masm()->TryCallStub(&stub); |
1070 *failure = Failure::cast(result); | 1073 if (!try_call_result->ToObject(&result)) { |
1071 return false; | 1074 *failure = Failure::cast(result); |
1072 } | 1075 return false; |
1073 | 1076 } |
1074 // We need to avoid using eax since that now holds the result. | |
1075 Register tmp = scratch2.is(eax) ? reg : scratch2; | |
1076 // Emitting PopHandleScope may try to allocate. Do not allow the | |
1077 // assembler to perform a garbage collection but instead return a | |
1078 // failure object. | |
1079 result = masm()->TryPopHandleScope(eax, tmp); | |
1080 if (result->IsFailure()) { | |
1081 *failure = Failure::cast(result); | |
1082 return false; | |
1083 } | 1077 } |
1084 __ LeaveInternalFrame(); | 1078 __ LeaveInternalFrame(); |
1085 | 1079 |
1086 __ ret(0); | 1080 __ ret(0); |
1087 return true; | 1081 return true; |
1088 } | 1082 } |
1089 | 1083 |
1090 | 1084 |
1091 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1085 void StubCompiler::GenerateLoadConstant(JSObject* object, |
1092 JSObject* holder, | 1086 JSObject* holder, |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), | 1301 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), |
1308 Immediate(Handle<SharedFunctionInfo>(function->shared()))); | 1302 Immediate(Handle<SharedFunctionInfo>(function->shared()))); |
1309 __ j(not_equal, miss, not_taken); | 1303 __ j(not_equal, miss, not_taken); |
1310 } else { | 1304 } else { |
1311 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); | 1305 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); |
1312 __ j(not_equal, miss, not_taken); | 1306 __ j(not_equal, miss, not_taken); |
1313 } | 1307 } |
1314 } | 1308 } |
1315 | 1309 |
1316 | 1310 |
1317 Object* CallStubCompiler::GenerateMissBranch() { | 1311 MaybeObject* CallStubCompiler::GenerateMissBranch() { |
1318 Object* obj = StubCache::ComputeCallMiss(arguments().immediate(), kind_); | 1312 Object* obj; |
1319 if (obj->IsFailure()) return obj; | 1313 { MaybeObject* maybe_obj = |
| 1314 StubCache::ComputeCallMiss(arguments().immediate(), kind_); |
| 1315 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1316 } |
1320 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1317 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1321 return obj; | 1318 return obj; |
1322 } | 1319 } |
1323 | 1320 |
1324 | 1321 |
1325 Object* CallStubCompiler::CompileCallField(JSObject* object, | 1322 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField( |
1326 JSObject* holder, | 1323 JSObject* object, |
1327 int index, | 1324 JSObject* holder, |
1328 String* name) { | 1325 int index, |
| 1326 String* name) { |
1329 // ----------- S t a t e ------------- | 1327 // ----------- S t a t e ------------- |
1330 // -- ecx : name | 1328 // -- ecx : name |
1331 // -- esp[0] : return address | 1329 // -- esp[0] : return address |
1332 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1330 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1333 // -- ... | 1331 // -- ... |
1334 // -- esp[(argc + 1) * 4] : receiver | 1332 // -- esp[(argc + 1) * 4] : receiver |
1335 // ----------------------------------- | 1333 // ----------------------------------- |
1336 Label miss; | 1334 Label miss; |
1337 | 1335 |
1338 GenerateNameCheck(name, &miss); | 1336 GenerateNameCheck(name, &miss); |
(...skipping 23 matching lines...) Expand all Loading... |
1362 if (object->IsGlobalObject()) { | 1360 if (object->IsGlobalObject()) { |
1363 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 1361 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
1364 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 1362 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
1365 } | 1363 } |
1366 | 1364 |
1367 // Invoke the function. | 1365 // Invoke the function. |
1368 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); | 1366 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); |
1369 | 1367 |
1370 // Handle call cache miss. | 1368 // Handle call cache miss. |
1371 __ bind(&miss); | 1369 __ bind(&miss); |
1372 Object* obj = GenerateMissBranch(); | 1370 Object* obj; |
1373 if (obj->IsFailure()) return obj; | 1371 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1372 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1373 } |
1374 | 1374 |
1375 // Return the generated code. | 1375 // Return the generated code. |
1376 return GetCode(FIELD, name); | 1376 return GetCode(FIELD, name); |
1377 } | 1377 } |
1378 | 1378 |
1379 | 1379 |
1380 Object* CallStubCompiler::CompileArrayPushCall(Object* object, | 1380 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
1381 JSObject* holder, | 1381 JSObject* holder, |
1382 JSGlobalPropertyCell* cell, | 1382 JSGlobalPropertyCell* cell, |
1383 JSFunction* function, | 1383 JSFunction* function, |
1384 String* name) { | 1384 String* name) { |
1385 // ----------- S t a t e ------------- | 1385 // ----------- S t a t e ------------- |
1386 // -- ecx : name | 1386 // -- ecx : name |
1387 // -- esp[0] : return address | 1387 // -- esp[0] : return address |
1388 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1388 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1389 // -- ... | 1389 // -- ... |
1390 // -- esp[(argc + 1) * 4] : receiver | 1390 // -- esp[(argc + 1) * 4] : receiver |
1391 // ----------------------------------- | 1391 // ----------------------------------- |
1392 | 1392 |
1393 // If object is not an array, bail out to regular call. | 1393 // If object is not an array, bail out to regular call. |
1394 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); | 1394 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1458 __ ret((argc + 1) * kPointerSize); | 1458 __ ret((argc + 1) * kPointerSize); |
1459 | 1459 |
1460 __ bind(&with_write_barrier); | 1460 __ bind(&with_write_barrier); |
1461 | 1461 |
1462 __ InNewSpace(ebx, ecx, equal, &exit); | 1462 __ InNewSpace(ebx, ecx, equal, &exit); |
1463 | 1463 |
1464 __ RecordWriteHelper(ebx, edx, ecx); | 1464 __ RecordWriteHelper(ebx, edx, ecx); |
1465 __ ret((argc + 1) * kPointerSize); | 1465 __ ret((argc + 1) * kPointerSize); |
1466 | 1466 |
1467 __ bind(&attempt_to_grow_elements); | 1467 __ bind(&attempt_to_grow_elements); |
| 1468 if (!FLAG_inline_new) { |
| 1469 __ jmp(&call_builtin); |
| 1470 } |
| 1471 |
1468 ExternalReference new_space_allocation_top = | 1472 ExternalReference new_space_allocation_top = |
1469 ExternalReference::new_space_allocation_top_address(); | 1473 ExternalReference::new_space_allocation_top_address(); |
1470 ExternalReference new_space_allocation_limit = | 1474 ExternalReference new_space_allocation_limit = |
1471 ExternalReference::new_space_allocation_limit_address(); | 1475 ExternalReference::new_space_allocation_limit_address(); |
1472 | 1476 |
1473 const int kAllocationDelta = 4; | 1477 const int kAllocationDelta = 4; |
1474 // Load top. | 1478 // Load top. |
1475 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); | 1479 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); |
1476 | 1480 |
1477 // Check if it's the end of elements. | 1481 // Check if it's the end of elements. |
(...skipping 30 matching lines...) Expand all Loading... |
1508 __ ret((argc + 1) * kPointerSize); | 1512 __ ret((argc + 1) * kPointerSize); |
1509 } | 1513 } |
1510 | 1514 |
1511 __ bind(&call_builtin); | 1515 __ bind(&call_builtin); |
1512 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush), | 1516 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush), |
1513 argc + 1, | 1517 argc + 1, |
1514 1); | 1518 1); |
1515 } | 1519 } |
1516 | 1520 |
1517 __ bind(&miss); | 1521 __ bind(&miss); |
1518 Object* obj = GenerateMissBranch(); | 1522 Object* obj; |
1519 if (obj->IsFailure()) return obj; | 1523 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1524 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1525 } |
1520 | 1526 |
1521 // Return the generated code. | 1527 // Return the generated code. |
1522 return GetCode(function); | 1528 return GetCode(function); |
1523 } | 1529 } |
1524 | 1530 |
1525 | 1531 |
1526 Object* CallStubCompiler::CompileArrayPopCall(Object* object, | 1532 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, |
1527 JSObject* holder, | 1533 JSObject* holder, |
1528 JSGlobalPropertyCell* cell, | 1534 JSGlobalPropertyCell* cell, |
1529 JSFunction* function, | 1535 JSFunction* function, |
1530 String* name) { | 1536 String* name) { |
1531 // ----------- S t a t e ------------- | 1537 // ----------- S t a t e ------------- |
1532 // -- ecx : name | 1538 // -- ecx : name |
1533 // -- esp[0] : return address | 1539 // -- esp[0] : return address |
1534 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1540 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1535 // -- ... | 1541 // -- ... |
1536 // -- esp[(argc + 1) * 4] : receiver | 1542 // -- esp[(argc + 1) * 4] : receiver |
1537 // ----------------------------------- | 1543 // ----------------------------------- |
1538 | 1544 |
1539 // If object is not an array, bail out to regular call. | 1545 // If object is not an array, bail out to regular call. |
1540 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); | 1546 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1589 __ bind(&return_undefined); | 1595 __ bind(&return_undefined); |
1590 __ mov(eax, Immediate(Factory::undefined_value())); | 1596 __ mov(eax, Immediate(Factory::undefined_value())); |
1591 __ ret((argc + 1) * kPointerSize); | 1597 __ ret((argc + 1) * kPointerSize); |
1592 | 1598 |
1593 __ bind(&call_builtin); | 1599 __ bind(&call_builtin); |
1594 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), | 1600 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), |
1595 argc + 1, | 1601 argc + 1, |
1596 1); | 1602 1); |
1597 | 1603 |
1598 __ bind(&miss); | 1604 __ bind(&miss); |
1599 Object* obj = GenerateMissBranch(); | 1605 Object* obj; |
1600 if (obj->IsFailure()) return obj; | 1606 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1607 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1608 } |
1601 | 1609 |
1602 // Return the generated code. | 1610 // Return the generated code. |
1603 return GetCode(function); | 1611 return GetCode(function); |
1604 } | 1612 } |
1605 | 1613 |
1606 | 1614 |
1607 Object* CallStubCompiler::CompileStringCharCodeAtCall( | 1615 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( |
1608 Object* object, | 1616 Object* object, |
1609 JSObject* holder, | 1617 JSObject* holder, |
1610 JSGlobalPropertyCell* cell, | 1618 JSGlobalPropertyCell* cell, |
1611 JSFunction* function, | 1619 JSFunction* function, |
1612 String* name) { | 1620 String* name) { |
1613 // ----------- S t a t e ------------- | 1621 // ----------- S t a t e ------------- |
1614 // -- ecx : function name | 1622 // -- ecx : function name |
1615 // -- esp[0] : return address | 1623 // -- esp[0] : return address |
1616 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1624 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1617 // -- ... | 1625 // -- ... |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1659 __ ret((argc + 1) * kPointerSize); | 1667 __ ret((argc + 1) * kPointerSize); |
1660 | 1668 |
1661 ICRuntimeCallHelper call_helper; | 1669 ICRuntimeCallHelper call_helper; |
1662 char_code_at_generator.GenerateSlow(masm(), call_helper); | 1670 char_code_at_generator.GenerateSlow(masm(), call_helper); |
1663 | 1671 |
1664 __ bind(&index_out_of_range); | 1672 __ bind(&index_out_of_range); |
1665 __ Set(eax, Immediate(Factory::nan_value())); | 1673 __ Set(eax, Immediate(Factory::nan_value())); |
1666 __ ret((argc + 1) * kPointerSize); | 1674 __ ret((argc + 1) * kPointerSize); |
1667 | 1675 |
1668 __ bind(&miss); | 1676 __ bind(&miss); |
1669 Object* obj = GenerateMissBranch(); | 1677 Object* obj; |
1670 if (obj->IsFailure()) return obj; | 1678 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1679 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1680 } |
1671 | 1681 |
1672 // Return the generated code. | 1682 // Return the generated code. |
1673 return GetCode(function); | 1683 return GetCode(function); |
1674 } | 1684 } |
1675 | 1685 |
1676 | 1686 |
1677 Object* CallStubCompiler::CompileStringCharAtCall(Object* object, | 1687 MaybeObject* CallStubCompiler::CompileStringCharAtCall( |
1678 JSObject* holder, | 1688 Object* object, |
1679 JSGlobalPropertyCell* cell, | 1689 JSObject* holder, |
1680 JSFunction* function, | 1690 JSGlobalPropertyCell* cell, |
1681 String* name) { | 1691 JSFunction* function, |
| 1692 String* name) { |
1682 // ----------- S t a t e ------------- | 1693 // ----------- S t a t e ------------- |
1683 // -- ecx : function name | 1694 // -- ecx : function name |
1684 // -- esp[0] : return address | 1695 // -- esp[0] : return address |
1685 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1696 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1686 // -- ... | 1697 // -- ... |
1687 // -- esp[(argc + 1) * 4] : receiver | 1698 // -- esp[(argc + 1) * 4] : receiver |
1688 // ----------------------------------- | 1699 // ----------------------------------- |
1689 | 1700 |
1690 // If object is not a string, bail out to regular call. | 1701 // If object is not a string, bail out to regular call. |
1691 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); | 1702 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1731 __ ret((argc + 1) * kPointerSize); | 1742 __ ret((argc + 1) * kPointerSize); |
1732 | 1743 |
1733 ICRuntimeCallHelper call_helper; | 1744 ICRuntimeCallHelper call_helper; |
1734 char_at_generator.GenerateSlow(masm(), call_helper); | 1745 char_at_generator.GenerateSlow(masm(), call_helper); |
1735 | 1746 |
1736 __ bind(&index_out_of_range); | 1747 __ bind(&index_out_of_range); |
1737 __ Set(eax, Immediate(Factory::empty_string())); | 1748 __ Set(eax, Immediate(Factory::empty_string())); |
1738 __ ret((argc + 1) * kPointerSize); | 1749 __ ret((argc + 1) * kPointerSize); |
1739 | 1750 |
1740 __ bind(&miss); | 1751 __ bind(&miss); |
1741 Object* obj = GenerateMissBranch(); | 1752 Object* obj; |
1742 if (obj->IsFailure()) return obj; | 1753 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1754 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1755 } |
1743 | 1756 |
1744 // Return the generated code. | 1757 // Return the generated code. |
1745 return GetCode(function); | 1758 return GetCode(function); |
1746 } | 1759 } |
1747 | 1760 |
1748 | 1761 |
1749 Object* CallStubCompiler::CompileStringFromCharCodeCall( | 1762 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( |
1750 Object* object, | 1763 Object* object, |
1751 JSObject* holder, | 1764 JSObject* holder, |
1752 JSGlobalPropertyCell* cell, | 1765 JSGlobalPropertyCell* cell, |
1753 JSFunction* function, | 1766 JSFunction* function, |
1754 String* name) { | 1767 String* name) { |
1755 // ----------- S t a t e ------------- | 1768 // ----------- S t a t e ------------- |
1756 // -- ecx : function name | 1769 // -- ecx : function name |
1757 // -- esp[0] : return address | 1770 // -- esp[0] : return address |
1758 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1771 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1759 // -- ... | 1772 // -- ... |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1804 ICRuntimeCallHelper call_helper; | 1817 ICRuntimeCallHelper call_helper; |
1805 char_from_code_generator.GenerateSlow(masm(), call_helper); | 1818 char_from_code_generator.GenerateSlow(masm(), call_helper); |
1806 | 1819 |
1807 // Tail call the full function. We do not have to patch the receiver | 1820 // Tail call the full function. We do not have to patch the receiver |
1808 // because the function makes no use of it. | 1821 // because the function makes no use of it. |
1809 __ bind(&slow); | 1822 __ bind(&slow); |
1810 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 1823 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
1811 | 1824 |
1812 __ bind(&miss); | 1825 __ bind(&miss); |
1813 // ecx: function name. | 1826 // ecx: function name. |
1814 Object* obj = GenerateMissBranch(); | 1827 Object* obj; |
1815 if (obj->IsFailure()) return obj; | 1828 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1829 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1830 } |
1816 | 1831 |
1817 // Return the generated code. | 1832 // Return the generated code. |
1818 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 1833 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); |
1819 } | 1834 } |
1820 | 1835 |
1821 | 1836 |
1822 Object* CallStubCompiler::CompileMathFloorCall(Object* object, | 1837 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, |
1823 JSObject* holder, | 1838 JSObject* holder, |
1824 JSGlobalPropertyCell* cell, | 1839 JSGlobalPropertyCell* cell, |
1825 JSFunction* function, | 1840 JSFunction* function, |
1826 String* name) { | 1841 String* name) { |
1827 // ----------- S t a t e ------------- | 1842 // ----------- S t a t e ------------- |
1828 // -- ecx : name | 1843 // -- ecx : name |
1829 // -- esp[0] : return address | 1844 // -- esp[0] : return address |
1830 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1845 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1831 // -- ... | 1846 // -- ... |
1832 // -- esp[(argc + 1) * 4] : receiver | 1847 // -- esp[(argc + 1) * 4] : receiver |
1833 // ----------------------------------- | 1848 // ----------------------------------- |
1834 | 1849 |
1835 if (!CpuFeatures::IsSupported(SSE2)) return Heap::undefined_value(); | 1850 if (!CpuFeatures::IsSupported(SSE2)) return Heap::undefined_value(); |
1836 CpuFeatures::Scope use_sse2(SSE2); | 1851 CpuFeatures::Scope use_sse2(SSE2); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1929 __ mov(eax, Operand(esp, 1 * kPointerSize)); | 1944 __ mov(eax, Operand(esp, 1 * kPointerSize)); |
1930 __ ret(2 * kPointerSize); | 1945 __ ret(2 * kPointerSize); |
1931 | 1946 |
1932 // Tail call the full function. We do not have to patch the receiver | 1947 // Tail call the full function. We do not have to patch the receiver |
1933 // because the function makes no use of it. | 1948 // because the function makes no use of it. |
1934 __ bind(&slow); | 1949 __ bind(&slow); |
1935 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 1950 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
1936 | 1951 |
1937 __ bind(&miss); | 1952 __ bind(&miss); |
1938 // ecx: function name. | 1953 // ecx: function name. |
1939 Object* obj = GenerateMissBranch(); | 1954 Object* obj; |
1940 if (obj->IsFailure()) return obj; | 1955 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1956 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1957 } |
1941 | 1958 |
1942 // Return the generated code. | 1959 // Return the generated code. |
1943 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 1960 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); |
1944 } | 1961 } |
1945 | 1962 |
1946 | 1963 |
1947 Object* CallStubCompiler::CompileMathAbsCall(Object* object, | 1964 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, |
1948 JSObject* holder, | 1965 JSObject* holder, |
1949 JSGlobalPropertyCell* cell, | 1966 JSGlobalPropertyCell* cell, |
1950 JSFunction* function, | 1967 JSFunction* function, |
1951 String* name) { | 1968 String* name) { |
1952 // ----------- S t a t e ------------- | 1969 // ----------- S t a t e ------------- |
1953 // -- ecx : name | 1970 // -- ecx : name |
1954 // -- esp[0] : return address | 1971 // -- esp[0] : return address |
1955 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1972 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1956 // -- ... | 1973 // -- ... |
1957 // -- esp[(argc + 1) * 4] : receiver | 1974 // -- esp[(argc + 1) * 4] : receiver |
1958 // ----------------------------------- | 1975 // ----------------------------------- |
1959 | 1976 |
1960 const int argc = arguments().immediate(); | 1977 const int argc = arguments().immediate(); |
1961 | 1978 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2032 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); | 2049 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); |
2033 __ ret(2 * kPointerSize); | 2050 __ ret(2 * kPointerSize); |
2034 | 2051 |
2035 // Tail call the full function. We do not have to patch the receiver | 2052 // Tail call the full function. We do not have to patch the receiver |
2036 // because the function makes no use of it. | 2053 // because the function makes no use of it. |
2037 __ bind(&slow); | 2054 __ bind(&slow); |
2038 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 2055 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
2039 | 2056 |
2040 __ bind(&miss); | 2057 __ bind(&miss); |
2041 // ecx: function name. | 2058 // ecx: function name. |
2042 Object* obj = GenerateMissBranch(); | 2059 Object* obj; |
2043 if (obj->IsFailure()) return obj; | 2060 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 2061 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2062 } |
2044 | 2063 |
2045 // Return the generated code. | 2064 // Return the generated code. |
2046 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2065 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); |
2047 } | 2066 } |
2048 | 2067 |
2049 | 2068 |
2050 Object* CallStubCompiler::CompileCallConstant(Object* object, | 2069 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, |
2051 JSObject* holder, | 2070 JSObject* holder, |
2052 JSFunction* function, | 2071 JSFunction* function, |
2053 String* name, | 2072 String* name, |
2054 CheckType check) { | 2073 CheckType check) { |
2055 // ----------- S t a t e ------------- | 2074 // ----------- S t a t e ------------- |
2056 // -- ecx : name | 2075 // -- ecx : name |
2057 // -- esp[0] : return address | 2076 // -- esp[0] : return address |
2058 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2077 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
2059 // -- ... | 2078 // -- ... |
2060 // -- esp[(argc + 1) * 4] : receiver | 2079 // -- esp[(argc + 1) * 4] : receiver |
2061 // ----------------------------------- | 2080 // ----------------------------------- |
2062 | 2081 |
2063 SharedFunctionInfo* function_info = function->shared(); | 2082 SharedFunctionInfo* function_info = function->shared(); |
2064 if (function_info->HasCustomCallGenerator()) { | 2083 if (function_info->HasCustomCallGenerator()) { |
2065 const int id = function_info->custom_call_generator_id(); | 2084 const int id = function_info->custom_call_generator_id(); |
2066 Object* result = CompileCustomCall( | 2085 MaybeObject* maybe_result = CompileCustomCall( |
2067 id, object, holder, NULL, function, name); | 2086 id, object, holder, NULL, function, name); |
| 2087 Object* result; |
| 2088 if (!maybe_result->ToObject(&result)) return maybe_result; |
2068 // undefined means bail out to regular compiler. | 2089 // undefined means bail out to regular compiler. |
2069 if (!result->IsUndefined()) return result; | 2090 if (!result->IsUndefined()) return result; |
2070 } | 2091 } |
2071 | 2092 |
2072 Label miss_in_smi_check; | 2093 Label miss_in_smi_check; |
2073 | 2094 |
2074 GenerateNameCheck(name, &miss_in_smi_check); | 2095 GenerateNameCheck(name, &miss_in_smi_check); |
2075 | 2096 |
2076 // Get the receiver from the stack. | 2097 // Get the receiver from the stack. |
2077 const int argc = arguments().immediate(); | 2098 const int argc = arguments().immediate(); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2185 } else { | 2206 } else { |
2186 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 2207 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
2187 } | 2208 } |
2188 | 2209 |
2189 // Handle call cache miss. | 2210 // Handle call cache miss. |
2190 __ bind(&miss); | 2211 __ bind(&miss); |
2191 if (depth != kInvalidProtoDepth) { | 2212 if (depth != kInvalidProtoDepth) { |
2192 FreeSpaceForFastApiCall(masm(), eax); | 2213 FreeSpaceForFastApiCall(masm(), eax); |
2193 } | 2214 } |
2194 __ bind(&miss_in_smi_check); | 2215 __ bind(&miss_in_smi_check); |
2195 Object* obj = GenerateMissBranch(); | 2216 Object* obj; |
2196 if (obj->IsFailure()) return obj; | 2217 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 2218 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2219 } |
2197 | 2220 |
2198 // Return the generated code. | 2221 // Return the generated code. |
2199 return GetCode(function); | 2222 return GetCode(function); |
2200 } | 2223 } |
2201 | 2224 |
2202 | 2225 |
2203 Object* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 2226 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, |
2204 JSObject* holder, | 2227 JSObject* holder, |
2205 String* name) { | 2228 String* name) { |
2206 // ----------- S t a t e ------------- | 2229 // ----------- S t a t e ------------- |
2207 // -- ecx : name | 2230 // -- ecx : name |
2208 // -- esp[0] : return address | 2231 // -- esp[0] : return address |
2209 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2232 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
2210 // -- ... | 2233 // -- ... |
2211 // -- esp[(argc + 1) * 4] : receiver | 2234 // -- esp[(argc + 1) * 4] : receiver |
2212 // ----------------------------------- | 2235 // ----------------------------------- |
2213 Label miss; | 2236 Label miss; |
2214 | 2237 |
2215 GenerateNameCheck(name, &miss); | 2238 GenerateNameCheck(name, &miss); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2250 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2273 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
2251 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2274 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
2252 } | 2275 } |
2253 | 2276 |
2254 // Invoke the function. | 2277 // Invoke the function. |
2255 __ mov(edi, eax); | 2278 __ mov(edi, eax); |
2256 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); | 2279 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); |
2257 | 2280 |
2258 // Handle load cache miss. | 2281 // Handle load cache miss. |
2259 __ bind(&miss); | 2282 __ bind(&miss); |
2260 Object* obj = GenerateMissBranch(); | 2283 Object* obj; |
2261 if (obj->IsFailure()) return obj; | 2284 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 2285 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2286 } |
2262 | 2287 |
2263 // Return the generated code. | 2288 // Return the generated code. |
2264 return GetCode(INTERCEPTOR, name); | 2289 return GetCode(INTERCEPTOR, name); |
2265 } | 2290 } |
2266 | 2291 |
2267 | 2292 |
2268 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2293 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
2269 GlobalObject* holder, | 2294 GlobalObject* holder, |
2270 JSGlobalPropertyCell* cell, | 2295 JSGlobalPropertyCell* cell, |
2271 JSFunction* function, | 2296 JSFunction* function, |
2272 String* name) { | 2297 String* name) { |
2273 // ----------- S t a t e ------------- | 2298 // ----------- S t a t e ------------- |
2274 // -- ecx : name | 2299 // -- ecx : name |
2275 // -- esp[0] : return address | 2300 // -- esp[0] : return address |
2276 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2301 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
2277 // -- ... | 2302 // -- ... |
2278 // -- esp[(argc + 1) * 4] : receiver | 2303 // -- esp[(argc + 1) * 4] : receiver |
2279 // ----------------------------------- | 2304 // ----------------------------------- |
2280 | 2305 |
2281 SharedFunctionInfo* function_info = function->shared(); | 2306 SharedFunctionInfo* function_info = function->shared(); |
2282 if (function_info->HasCustomCallGenerator()) { | 2307 if (function_info->HasCustomCallGenerator()) { |
2283 const int id = function_info->custom_call_generator_id(); | 2308 const int id = function_info->custom_call_generator_id(); |
2284 Object* result = CompileCustomCall( | 2309 MaybeObject* maybe_result = CompileCustomCall( |
2285 id, object, holder, cell, function, name); | 2310 id, object, holder, cell, function, name); |
| 2311 Object* result; |
| 2312 if (!maybe_result->ToObject(&result)) return maybe_result; |
2286 // undefined means bail out to regular compiler. | 2313 // undefined means bail out to regular compiler. |
2287 if (!result->IsUndefined()) return result; | 2314 if (!result->IsUndefined()) return result; |
2288 } | 2315 } |
2289 | 2316 |
2290 Label miss; | 2317 Label miss; |
2291 | 2318 |
2292 GenerateNameCheck(name, &miss); | 2319 GenerateNameCheck(name, &miss); |
2293 | 2320 |
2294 // Get the number of arguments. | 2321 // Get the number of arguments. |
2295 const int argc = arguments().immediate(); | 2322 const int argc = arguments().immediate(); |
(...skipping 15 matching lines...) Expand all Loading... |
2311 __ IncrementCounter(&Counters::call_global_inline, 1); | 2338 __ IncrementCounter(&Counters::call_global_inline, 1); |
2312 ASSERT(function->is_compiled()); | 2339 ASSERT(function->is_compiled()); |
2313 Handle<Code> code(function->code()); | 2340 Handle<Code> code(function->code()); |
2314 ParameterCount expected(function->shared()->formal_parameter_count()); | 2341 ParameterCount expected(function->shared()->formal_parameter_count()); |
2315 __ InvokeCode(code, expected, arguments(), | 2342 __ InvokeCode(code, expected, arguments(), |
2316 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 2343 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
2317 | 2344 |
2318 // Handle call cache miss. | 2345 // Handle call cache miss. |
2319 __ bind(&miss); | 2346 __ bind(&miss); |
2320 __ IncrementCounter(&Counters::call_global_inline_miss, 1); | 2347 __ IncrementCounter(&Counters::call_global_inline_miss, 1); |
2321 Object* obj = GenerateMissBranch(); | 2348 Object* obj; |
2322 if (obj->IsFailure()) return obj; | 2349 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 2350 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2351 } |
2323 | 2352 |
2324 // Return the generated code. | 2353 // Return the generated code. |
2325 return GetCode(NORMAL, name); | 2354 return GetCode(NORMAL, name); |
2326 } | 2355 } |
2327 | 2356 |
2328 | 2357 |
2329 Object* StoreStubCompiler::CompileStoreField(JSObject* object, | 2358 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, |
2330 int index, | 2359 int index, |
2331 Map* transition, | 2360 Map* transition, |
2332 String* name) { | 2361 String* name) { |
2333 // ----------- S t a t e ------------- | 2362 // ----------- S t a t e ------------- |
2334 // -- eax : value | 2363 // -- eax : value |
2335 // -- ecx : name | 2364 // -- ecx : name |
2336 // -- edx : receiver | 2365 // -- edx : receiver |
2337 // -- esp[0] : return address | 2366 // -- esp[0] : return address |
2338 // ----------------------------------- | 2367 // ----------------------------------- |
2339 Label miss; | 2368 Label miss; |
2340 | 2369 |
2341 // Generate store field code. Trashes the name register. | 2370 // Generate store field code. Trashes the name register. |
2342 GenerateStoreField(masm(), | 2371 GenerateStoreField(masm(), |
2343 object, | 2372 object, |
2344 index, | 2373 index, |
2345 transition, | 2374 transition, |
2346 edx, ecx, ebx, | 2375 edx, ecx, ebx, |
2347 &miss); | 2376 &miss); |
2348 | 2377 |
2349 // Handle store cache miss. | 2378 // Handle store cache miss. |
2350 __ bind(&miss); | 2379 __ bind(&miss); |
2351 __ mov(ecx, Immediate(Handle<String>(name))); // restore name | 2380 __ mov(ecx, Immediate(Handle<String>(name))); // restore name |
2352 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 2381 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); |
2353 __ jmp(ic, RelocInfo::CODE_TARGET); | 2382 __ jmp(ic, RelocInfo::CODE_TARGET); |
2354 | 2383 |
2355 // Return the generated code. | 2384 // Return the generated code. |
2356 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2385 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
2357 } | 2386 } |
2358 | 2387 |
2359 | 2388 |
2360 Object* StoreStubCompiler::CompileStoreCallback(JSObject* object, | 2389 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, |
2361 AccessorInfo* callback, | 2390 AccessorInfo* callback, |
2362 String* name) { | 2391 String* name) { |
2363 // ----------- S t a t e ------------- | 2392 // ----------- S t a t e ------------- |
2364 // -- eax : value | 2393 // -- eax : value |
2365 // -- ecx : name | 2394 // -- ecx : name |
2366 // -- edx : receiver | 2395 // -- edx : receiver |
2367 // -- esp[0] : return address | 2396 // -- esp[0] : return address |
2368 // ----------------------------------- | 2397 // ----------------------------------- |
2369 Label miss; | 2398 Label miss; |
2370 | 2399 |
2371 // Check that the object isn't a smi. | 2400 // Check that the object isn't a smi. |
2372 __ test(edx, Immediate(kSmiTagMask)); | 2401 __ test(edx, Immediate(kSmiTagMask)); |
(...skipping 28 matching lines...) Expand all Loading... |
2401 // Handle store cache miss. | 2430 // Handle store cache miss. |
2402 __ bind(&miss); | 2431 __ bind(&miss); |
2403 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 2432 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); |
2404 __ jmp(ic, RelocInfo::CODE_TARGET); | 2433 __ jmp(ic, RelocInfo::CODE_TARGET); |
2405 | 2434 |
2406 // Return the generated code. | 2435 // Return the generated code. |
2407 return GetCode(CALLBACKS, name); | 2436 return GetCode(CALLBACKS, name); |
2408 } | 2437 } |
2409 | 2438 |
2410 | 2439 |
2411 Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, | 2440 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, |
2412 String* name) { | 2441 String* name) { |
2413 // ----------- S t a t e ------------- | 2442 // ----------- S t a t e ------------- |
2414 // -- eax : value | 2443 // -- eax : value |
2415 // -- ecx : name | 2444 // -- ecx : name |
2416 // -- edx : receiver | 2445 // -- edx : receiver |
2417 // -- esp[0] : return address | 2446 // -- esp[0] : return address |
2418 // ----------------------------------- | 2447 // ----------------------------------- |
2419 Label miss; | 2448 Label miss; |
2420 | 2449 |
2421 // Check that the object isn't a smi. | 2450 // Check that the object isn't a smi. |
2422 __ test(edx, Immediate(kSmiTagMask)); | 2451 __ test(edx, Immediate(kSmiTagMask)); |
(...skipping 27 matching lines...) Expand all Loading... |
2450 // Handle store cache miss. | 2479 // Handle store cache miss. |
2451 __ bind(&miss); | 2480 __ bind(&miss); |
2452 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 2481 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); |
2453 __ jmp(ic, RelocInfo::CODE_TARGET); | 2482 __ jmp(ic, RelocInfo::CODE_TARGET); |
2454 | 2483 |
2455 // Return the generated code. | 2484 // Return the generated code. |
2456 return GetCode(INTERCEPTOR, name); | 2485 return GetCode(INTERCEPTOR, name); |
2457 } | 2486 } |
2458 | 2487 |
2459 | 2488 |
2460 Object* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, | 2489 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, |
2461 JSGlobalPropertyCell* cell, | 2490 JSGlobalPropertyCell* cell, |
2462 String* name) { | 2491 String* name) { |
2463 // ----------- S t a t e ------------- | 2492 // ----------- S t a t e ------------- |
2464 // -- eax : value | 2493 // -- eax : value |
2465 // -- ecx : name | 2494 // -- ecx : name |
2466 // -- edx : receiver | 2495 // -- edx : receiver |
2467 // -- esp[0] : return address | 2496 // -- esp[0] : return address |
2468 // ----------------------------------- | 2497 // ----------------------------------- |
2469 Label miss; | 2498 Label miss; |
2470 | 2499 |
2471 // Check that the map of the global has not changed. | 2500 // Check that the map of the global has not changed. |
2472 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 2501 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), |
(...skipping 12 matching lines...) Expand all Loading... |
2485 __ bind(&miss); | 2514 __ bind(&miss); |
2486 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1); | 2515 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1); |
2487 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 2516 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); |
2488 __ jmp(ic, RelocInfo::CODE_TARGET); | 2517 __ jmp(ic, RelocInfo::CODE_TARGET); |
2489 | 2518 |
2490 // Return the generated code. | 2519 // Return the generated code. |
2491 return GetCode(NORMAL, name); | 2520 return GetCode(NORMAL, name); |
2492 } | 2521 } |
2493 | 2522 |
2494 | 2523 |
2495 Object* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 2524 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
2496 int index, | 2525 int index, |
2497 Map* transition, | 2526 Map* transition, |
2498 String* name) { | 2527 String* name) { |
2499 // ----------- S t a t e ------------- | 2528 // ----------- S t a t e ------------- |
2500 // -- eax : value | 2529 // -- eax : value |
2501 // -- ecx : key | 2530 // -- ecx : key |
2502 // -- edx : receiver | 2531 // -- edx : receiver |
2503 // -- esp[0] : return address | 2532 // -- esp[0] : return address |
2504 // ----------------------------------- | 2533 // ----------------------------------- |
2505 Label miss; | 2534 Label miss; |
2506 | 2535 |
2507 __ IncrementCounter(&Counters::keyed_store_field, 1); | 2536 __ IncrementCounter(&Counters::keyed_store_field, 1); |
2508 | 2537 |
(...skipping 13 matching lines...) Expand all Loading... |
2522 __ bind(&miss); | 2551 __ bind(&miss); |
2523 __ DecrementCounter(&Counters::keyed_store_field, 1); | 2552 __ DecrementCounter(&Counters::keyed_store_field, 1); |
2524 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 2553 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); |
2525 __ jmp(ic, RelocInfo::CODE_TARGET); | 2554 __ jmp(ic, RelocInfo::CODE_TARGET); |
2526 | 2555 |
2527 // Return the generated code. | 2556 // Return the generated code. |
2528 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2557 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
2529 } | 2558 } |
2530 | 2559 |
2531 | 2560 |
2532 Object* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2561 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, |
2533 JSObject* object, | 2562 JSObject* object, |
2534 JSObject* last) { | 2563 JSObject* last) { |
2535 // ----------- S t a t e ------------- | 2564 // ----------- S t a t e ------------- |
2536 // -- eax : receiver | 2565 // -- eax : receiver |
2537 // -- ecx : name | 2566 // -- ecx : name |
2538 // -- esp[0] : return address | 2567 // -- esp[0] : return address |
2539 // ----------------------------------- | 2568 // ----------------------------------- |
2540 Label miss; | 2569 Label miss; |
2541 | 2570 |
2542 // Check that the receiver isn't a smi. | 2571 // Check that the receiver isn't a smi. |
2543 __ test(eax, Immediate(kSmiTagMask)); | 2572 __ test(eax, Immediate(kSmiTagMask)); |
2544 __ j(zero, &miss, not_taken); | 2573 __ j(zero, &miss, not_taken); |
2545 | 2574 |
2546 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); | 2575 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); |
2547 | 2576 |
2548 // Check the maps of the full prototype chain. Also check that | 2577 // Check the maps of the full prototype chain. Also check that |
2549 // global property cells up to (but not including) the last object | 2578 // global property cells up to (but not including) the last object |
2550 // in the prototype chain are empty. | 2579 // in the prototype chain are empty. |
2551 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); | 2580 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); |
2552 | 2581 |
2553 // If the last object in the prototype chain is a global object, | 2582 // If the last object in the prototype chain is a global object, |
2554 // check that the global property cell is empty. | 2583 // check that the global property cell is empty. |
2555 if (last->IsGlobalObject()) { | 2584 if (last->IsGlobalObject()) { |
2556 Object* cell = GenerateCheckPropertyCell(masm(), | 2585 MaybeObject* cell = GenerateCheckPropertyCell(masm(), |
2557 GlobalObject::cast(last), | 2586 GlobalObject::cast(last), |
2558 name, | 2587 name, |
2559 edx, | 2588 edx, |
2560 &miss); | 2589 &miss); |
2561 if (cell->IsFailure()) { | 2590 if (cell->IsFailure()) { |
2562 miss.Unuse(); | 2591 miss.Unuse(); |
2563 return cell; | 2592 return cell; |
2564 } | 2593 } |
2565 } | 2594 } |
2566 | 2595 |
2567 // Return undefined if maps of the full prototype chain are still the | 2596 // Return undefined if maps of the full prototype chain are still the |
2568 // same and no global property with this name contains a value. | 2597 // same and no global property with this name contains a value. |
2569 __ mov(eax, Factory::undefined_value()); | 2598 __ mov(eax, Factory::undefined_value()); |
2570 __ ret(0); | 2599 __ ret(0); |
2571 | 2600 |
2572 __ bind(&miss); | 2601 __ bind(&miss); |
2573 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2602 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2574 | 2603 |
2575 // Return the generated code. | 2604 // Return the generated code. |
2576 return GetCode(NONEXISTENT, Heap::empty_string()); | 2605 return GetCode(NONEXISTENT, Heap::empty_string()); |
2577 } | 2606 } |
2578 | 2607 |
2579 | 2608 |
2580 Object* LoadStubCompiler::CompileLoadField(JSObject* object, | 2609 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, |
2581 JSObject* holder, | 2610 JSObject* holder, |
2582 int index, | 2611 int index, |
2583 String* name) { | 2612 String* name) { |
2584 // ----------- S t a t e ------------- | 2613 // ----------- S t a t e ------------- |
2585 // -- eax : receiver | 2614 // -- eax : receiver |
2586 // -- ecx : name | 2615 // -- ecx : name |
2587 // -- esp[0] : return address | 2616 // -- esp[0] : return address |
2588 // ----------------------------------- | 2617 // ----------------------------------- |
2589 Label miss; | 2618 Label miss; |
2590 | 2619 |
2591 GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss); | 2620 GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss); |
2592 __ bind(&miss); | 2621 __ bind(&miss); |
2593 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2622 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2594 | 2623 |
2595 // Return the generated code. | 2624 // Return the generated code. |
2596 return GetCode(FIELD, name); | 2625 return GetCode(FIELD, name); |
2597 } | 2626 } |
2598 | 2627 |
2599 | 2628 |
2600 Object* LoadStubCompiler::CompileLoadCallback(String* name, | 2629 MaybeObject* LoadStubCompiler::CompileLoadCallback(String* name, |
2601 JSObject* object, | 2630 JSObject* object, |
2602 JSObject* holder, | 2631 JSObject* holder, |
2603 AccessorInfo* callback) { | 2632 AccessorInfo* callback) { |
2604 // ----------- S t a t e ------------- | 2633 // ----------- S t a t e ------------- |
2605 // -- eax : receiver | 2634 // -- eax : receiver |
2606 // -- ecx : name | 2635 // -- ecx : name |
2607 // -- esp[0] : return address | 2636 // -- esp[0] : return address |
2608 // ----------------------------------- | 2637 // ----------------------------------- |
2609 Label miss; | 2638 Label miss; |
2610 | 2639 |
2611 Failure* failure = Failure::InternalError(); | 2640 Failure* failure = Failure::InternalError(); |
2612 bool success = GenerateLoadCallback(object, holder, eax, ecx, ebx, edx, edi, | 2641 bool success = GenerateLoadCallback(object, holder, eax, ecx, ebx, edx, edi, |
2613 callback, name, &miss, &failure); | 2642 callback, name, &miss, &failure); |
2614 if (!success) { | 2643 if (!success) { |
2615 miss.Unuse(); | 2644 miss.Unuse(); |
2616 return failure; | 2645 return failure; |
2617 } | 2646 } |
2618 | 2647 |
2619 __ bind(&miss); | 2648 __ bind(&miss); |
2620 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2649 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2621 | 2650 |
2622 // Return the generated code. | 2651 // Return the generated code. |
2623 return GetCode(CALLBACKS, name); | 2652 return GetCode(CALLBACKS, name); |
2624 } | 2653 } |
2625 | 2654 |
2626 | 2655 |
2627 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 2656 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, |
2628 JSObject* holder, | 2657 JSObject* holder, |
2629 Object* value, | 2658 Object* value, |
2630 String* name) { | 2659 String* name) { |
2631 // ----------- S t a t e ------------- | 2660 // ----------- S t a t e ------------- |
2632 // -- eax : receiver | 2661 // -- eax : receiver |
2633 // -- ecx : name | 2662 // -- ecx : name |
2634 // -- esp[0] : return address | 2663 // -- esp[0] : return address |
2635 // ----------------------------------- | 2664 // ----------------------------------- |
2636 Label miss; | 2665 Label miss; |
2637 | 2666 |
2638 GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss); | 2667 GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss); |
2639 __ bind(&miss); | 2668 __ bind(&miss); |
2640 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2669 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2641 | 2670 |
2642 // Return the generated code. | 2671 // Return the generated code. |
2643 return GetCode(CONSTANT_FUNCTION, name); | 2672 return GetCode(CONSTANT_FUNCTION, name); |
2644 } | 2673 } |
2645 | 2674 |
2646 | 2675 |
2647 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 2676 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
2648 JSObject* holder, | 2677 JSObject* holder, |
2649 String* name) { | 2678 String* name) { |
2650 // ----------- S t a t e ------------- | 2679 // ----------- S t a t e ------------- |
2651 // -- eax : receiver | 2680 // -- eax : receiver |
2652 // -- ecx : name | 2681 // -- ecx : name |
2653 // -- esp[0] : return address | 2682 // -- esp[0] : return address |
2654 // ----------------------------------- | 2683 // ----------------------------------- |
2655 Label miss; | 2684 Label miss; |
2656 | 2685 |
2657 LookupResult lookup; | 2686 LookupResult lookup; |
2658 LookupPostInterceptor(holder, name, &lookup); | 2687 LookupPostInterceptor(holder, name, &lookup); |
2659 | 2688 |
(...skipping 11 matching lines...) Expand all Loading... |
2671 &miss); | 2700 &miss); |
2672 | 2701 |
2673 __ bind(&miss); | 2702 __ bind(&miss); |
2674 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2703 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2675 | 2704 |
2676 // Return the generated code. | 2705 // Return the generated code. |
2677 return GetCode(INTERCEPTOR, name); | 2706 return GetCode(INTERCEPTOR, name); |
2678 } | 2707 } |
2679 | 2708 |
2680 | 2709 |
2681 Object* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 2710 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, |
2682 GlobalObject* holder, | 2711 GlobalObject* holder, |
2683 JSGlobalPropertyCell* cell, | 2712 JSGlobalPropertyCell* cell, |
2684 String* name, | 2713 String* name, |
2685 bool is_dont_delete) { | 2714 bool is_dont_delete) { |
2686 // ----------- S t a t e ------------- | 2715 // ----------- S t a t e ------------- |
2687 // -- eax : receiver | 2716 // -- eax : receiver |
2688 // -- ecx : name | 2717 // -- ecx : name |
2689 // -- esp[0] : return address | 2718 // -- esp[0] : return address |
2690 // ----------------------------------- | 2719 // ----------------------------------- |
2691 Label miss; | 2720 Label miss; |
2692 | 2721 |
2693 // If the object is the holder then we know that it's a global | 2722 // If the object is the holder then we know that it's a global |
2694 // object which can only happen for contextual loads. In this case, | 2723 // object which can only happen for contextual loads. In this case, |
2695 // the receiver cannot be a smi. | 2724 // the receiver cannot be a smi. |
(...skipping 24 matching lines...) Expand all Loading... |
2720 | 2749 |
2721 __ bind(&miss); | 2750 __ bind(&miss); |
2722 __ IncrementCounter(&Counters::named_load_global_stub_miss, 1); | 2751 __ IncrementCounter(&Counters::named_load_global_stub_miss, 1); |
2723 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2752 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2724 | 2753 |
2725 // Return the generated code. | 2754 // Return the generated code. |
2726 return GetCode(NORMAL, name); | 2755 return GetCode(NORMAL, name); |
2727 } | 2756 } |
2728 | 2757 |
2729 | 2758 |
2730 Object* KeyedLoadStubCompiler::CompileLoadField(String* name, | 2759 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, |
2731 JSObject* receiver, | 2760 JSObject* receiver, |
2732 JSObject* holder, | 2761 JSObject* holder, |
2733 int index) { | 2762 int index) { |
2734 // ----------- S t a t e ------------- | 2763 // ----------- S t a t e ------------- |
2735 // -- eax : key | 2764 // -- eax : key |
2736 // -- edx : receiver | 2765 // -- edx : receiver |
2737 // -- esp[0] : return address | 2766 // -- esp[0] : return address |
2738 // ----------------------------------- | 2767 // ----------------------------------- |
2739 Label miss; | 2768 Label miss; |
2740 | 2769 |
2741 __ IncrementCounter(&Counters::keyed_load_field, 1); | 2770 __ IncrementCounter(&Counters::keyed_load_field, 1); |
2742 | 2771 |
2743 // Check that the name has not changed. | 2772 // Check that the name has not changed. |
2744 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 2773 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
2745 __ j(not_equal, &miss, not_taken); | 2774 __ j(not_equal, &miss, not_taken); |
2746 | 2775 |
2747 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); | 2776 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); |
2748 | 2777 |
2749 __ bind(&miss); | 2778 __ bind(&miss); |
2750 __ DecrementCounter(&Counters::keyed_load_field, 1); | 2779 __ DecrementCounter(&Counters::keyed_load_field, 1); |
2751 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2780 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2752 | 2781 |
2753 // Return the generated code. | 2782 // Return the generated code. |
2754 return GetCode(FIELD, name); | 2783 return GetCode(FIELD, name); |
2755 } | 2784 } |
2756 | 2785 |
2757 | 2786 |
2758 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, | 2787 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( |
2759 JSObject* receiver, | 2788 String* name, |
2760 JSObject* holder, | 2789 JSObject* receiver, |
2761 AccessorInfo* callback) { | 2790 JSObject* holder, |
| 2791 AccessorInfo* callback) { |
2762 // ----------- S t a t e ------------- | 2792 // ----------- S t a t e ------------- |
2763 // -- eax : key | 2793 // -- eax : key |
2764 // -- edx : receiver | 2794 // -- edx : receiver |
2765 // -- esp[0] : return address | 2795 // -- esp[0] : return address |
2766 // ----------------------------------- | 2796 // ----------------------------------- |
2767 Label miss; | 2797 Label miss; |
2768 | 2798 |
2769 __ IncrementCounter(&Counters::keyed_load_callback, 1); | 2799 __ IncrementCounter(&Counters::keyed_load_callback, 1); |
2770 | 2800 |
2771 // Check that the name has not changed. | 2801 // Check that the name has not changed. |
(...skipping 11 matching lines...) Expand all Loading... |
2783 __ bind(&miss); | 2813 __ bind(&miss); |
2784 | 2814 |
2785 __ DecrementCounter(&Counters::keyed_load_callback, 1); | 2815 __ DecrementCounter(&Counters::keyed_load_callback, 1); |
2786 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2816 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2787 | 2817 |
2788 // Return the generated code. | 2818 // Return the generated code. |
2789 return GetCode(CALLBACKS, name); | 2819 return GetCode(CALLBACKS, name); |
2790 } | 2820 } |
2791 | 2821 |
2792 | 2822 |
2793 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 2823 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, |
2794 JSObject* receiver, | 2824 JSObject* receiver, |
2795 JSObject* holder, | 2825 JSObject* holder, |
2796 Object* value) { | 2826 Object* value) { |
2797 // ----------- S t a t e ------------- | 2827 // ----------- S t a t e ------------- |
2798 // -- eax : key | 2828 // -- eax : key |
2799 // -- edx : receiver | 2829 // -- edx : receiver |
2800 // -- esp[0] : return address | 2830 // -- esp[0] : return address |
2801 // ----------------------------------- | 2831 // ----------------------------------- |
2802 Label miss; | 2832 Label miss; |
2803 | 2833 |
2804 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); | 2834 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); |
2805 | 2835 |
2806 // Check that the name has not changed. | 2836 // Check that the name has not changed. |
2807 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 2837 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
2808 __ j(not_equal, &miss, not_taken); | 2838 __ j(not_equal, &miss, not_taken); |
2809 | 2839 |
2810 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, | 2840 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, |
2811 value, name, &miss); | 2841 value, name, &miss); |
2812 __ bind(&miss); | 2842 __ bind(&miss); |
2813 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); | 2843 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); |
2814 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2844 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2815 | 2845 |
2816 // Return the generated code. | 2846 // Return the generated code. |
2817 return GetCode(CONSTANT_FUNCTION, name); | 2847 return GetCode(CONSTANT_FUNCTION, name); |
2818 } | 2848 } |
2819 | 2849 |
2820 | 2850 |
2821 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 2851 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
2822 JSObject* holder, | 2852 JSObject* holder, |
2823 String* name) { | 2853 String* name) { |
2824 // ----------- S t a t e ------------- | 2854 // ----------- S t a t e ------------- |
2825 // -- eax : key | 2855 // -- eax : key |
2826 // -- edx : receiver | 2856 // -- edx : receiver |
2827 // -- esp[0] : return address | 2857 // -- esp[0] : return address |
2828 // ----------------------------------- | 2858 // ----------------------------------- |
2829 Label miss; | 2859 Label miss; |
2830 | 2860 |
2831 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); | 2861 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); |
2832 | 2862 |
2833 // Check that the name has not changed. | 2863 // Check that the name has not changed. |
(...skipping 14 matching lines...) Expand all Loading... |
2848 &miss); | 2878 &miss); |
2849 __ bind(&miss); | 2879 __ bind(&miss); |
2850 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); | 2880 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); |
2851 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2881 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2852 | 2882 |
2853 // Return the generated code. | 2883 // Return the generated code. |
2854 return GetCode(INTERCEPTOR, name); | 2884 return GetCode(INTERCEPTOR, name); |
2855 } | 2885 } |
2856 | 2886 |
2857 | 2887 |
2858 | 2888 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { |
2859 | |
2860 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | |
2861 // ----------- S t a t e ------------- | 2889 // ----------- S t a t e ------------- |
2862 // -- eax : key | 2890 // -- eax : key |
2863 // -- edx : receiver | 2891 // -- edx : receiver |
2864 // -- esp[0] : return address | 2892 // -- esp[0] : return address |
2865 // ----------------------------------- | 2893 // ----------------------------------- |
2866 Label miss; | 2894 Label miss; |
2867 | 2895 |
2868 __ IncrementCounter(&Counters::keyed_load_array_length, 1); | 2896 __ IncrementCounter(&Counters::keyed_load_array_length, 1); |
2869 | 2897 |
2870 // Check that the name has not changed. | 2898 // Check that the name has not changed. |
2871 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 2899 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
2872 __ j(not_equal, &miss, not_taken); | 2900 __ j(not_equal, &miss, not_taken); |
2873 | 2901 |
2874 GenerateLoadArrayLength(masm(), edx, ecx, &miss); | 2902 GenerateLoadArrayLength(masm(), edx, ecx, &miss); |
2875 __ bind(&miss); | 2903 __ bind(&miss); |
2876 __ DecrementCounter(&Counters::keyed_load_array_length, 1); | 2904 __ DecrementCounter(&Counters::keyed_load_array_length, 1); |
2877 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2905 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2878 | 2906 |
2879 // Return the generated code. | 2907 // Return the generated code. |
2880 return GetCode(CALLBACKS, name); | 2908 return GetCode(CALLBACKS, name); |
2881 } | 2909 } |
2882 | 2910 |
2883 | 2911 |
2884 Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 2912 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { |
2885 // ----------- S t a t e ------------- | 2913 // ----------- S t a t e ------------- |
2886 // -- eax : key | 2914 // -- eax : key |
2887 // -- edx : receiver | 2915 // -- edx : receiver |
2888 // -- esp[0] : return address | 2916 // -- esp[0] : return address |
2889 // ----------------------------------- | 2917 // ----------------------------------- |
2890 Label miss; | 2918 Label miss; |
2891 | 2919 |
2892 __ IncrementCounter(&Counters::keyed_load_string_length, 1); | 2920 __ IncrementCounter(&Counters::keyed_load_string_length, 1); |
2893 | 2921 |
2894 // Check that the name has not changed. | 2922 // Check that the name has not changed. |
2895 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 2923 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
2896 __ j(not_equal, &miss, not_taken); | 2924 __ j(not_equal, &miss, not_taken); |
2897 | 2925 |
2898 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss); | 2926 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss); |
2899 __ bind(&miss); | 2927 __ bind(&miss); |
2900 __ DecrementCounter(&Counters::keyed_load_string_length, 1); | 2928 __ DecrementCounter(&Counters::keyed_load_string_length, 1); |
2901 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2929 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2902 | 2930 |
2903 // Return the generated code. | 2931 // Return the generated code. |
2904 return GetCode(CALLBACKS, name); | 2932 return GetCode(CALLBACKS, name); |
2905 } | 2933 } |
2906 | 2934 |
2907 | 2935 |
2908 Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 2936 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
2909 // ----------- S t a t e ------------- | 2937 // ----------- S t a t e ------------- |
2910 // -- eax : key | 2938 // -- eax : key |
2911 // -- edx : receiver | 2939 // -- edx : receiver |
2912 // -- esp[0] : return address | 2940 // -- esp[0] : return address |
2913 // ----------------------------------- | 2941 // ----------------------------------- |
2914 Label miss; | 2942 Label miss; |
2915 | 2943 |
2916 __ IncrementCounter(&Counters::keyed_load_function_prototype, 1); | 2944 __ IncrementCounter(&Counters::keyed_load_function_prototype, 1); |
2917 | 2945 |
2918 // Check that the name has not changed. | 2946 // Check that the name has not changed. |
2919 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 2947 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
2920 __ j(not_equal, &miss, not_taken); | 2948 __ j(not_equal, &miss, not_taken); |
2921 | 2949 |
2922 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); | 2950 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); |
2923 __ bind(&miss); | 2951 __ bind(&miss); |
2924 __ DecrementCounter(&Counters::keyed_load_function_prototype, 1); | 2952 __ DecrementCounter(&Counters::keyed_load_function_prototype, 1); |
2925 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2953 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2926 | 2954 |
2927 // Return the generated code. | 2955 // Return the generated code. |
2928 return GetCode(CALLBACKS, name); | 2956 return GetCode(CALLBACKS, name); |
2929 } | 2957 } |
2930 | 2958 |
2931 | 2959 |
2932 // Specialized stub for constructing objects from functions which only have only | 2960 // Specialized stub for constructing objects from functions which only have only |
2933 // simple assignments of the form this.x = ...; in their body. | 2961 // simple assignments of the form this.x = ...; in their body. |
2934 Object* ConstructStubCompiler::CompileConstructStub( | 2962 MaybeObject* ConstructStubCompiler::CompileConstructStub( |
2935 SharedFunctionInfo* shared) { | 2963 SharedFunctionInfo* shared) { |
2936 // ----------- S t a t e ------------- | 2964 // ----------- S t a t e ------------- |
2937 // -- eax : argc | 2965 // -- eax : argc |
2938 // -- edi : constructor | 2966 // -- edi : constructor |
2939 // -- esp[0] : return address | 2967 // -- esp[0] : return address |
2940 // -- esp[4] : last argument | 2968 // -- esp[4] : last argument |
2941 // ----------------------------------- | 2969 // ----------------------------------- |
2942 Label generic_stub_call; | 2970 Label generic_stub_call; |
2943 #ifdef ENABLE_DEBUGGER_SUPPORT | 2971 #ifdef ENABLE_DEBUGGER_SUPPORT |
2944 // Check to see whether there are any break points in the function code. If | 2972 // Check to see whether there are any break points in the function code. If |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3064 // Return the generated code. | 3092 // Return the generated code. |
3065 return GetCode(); | 3093 return GetCode(); |
3066 } | 3094 } |
3067 | 3095 |
3068 | 3096 |
3069 #undef __ | 3097 #undef __ |
3070 | 3098 |
3071 } } // namespace v8::internal | 3099 } } // namespace v8::internal |
3072 | 3100 |
3073 #endif // V8_TARGET_ARCH_IA32 | 3101 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |