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