| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 __ movq(prototype, Operand(prototype, Context::SlotOffset(index))); | 209 __ movq(prototype, Operand(prototype, Context::SlotOffset(index))); |
| 210 // Load the initial map. The global functions all have initial maps. | 210 // Load the initial map. The global functions all have initial maps. |
| 211 __ movq(prototype, | 211 __ movq(prototype, |
| 212 FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); | 212 FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); |
| 213 // Load the prototype from the initial map. | 213 // Load the prototype from the initial map. |
| 214 __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | 214 __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); |
| 215 } | 215 } |
| 216 | 216 |
| 217 | 217 |
| 218 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( | 218 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( |
| 219 MacroAssembler* masm, int index, Register prototype) { | 219 MacroAssembler* masm, int index, Register prototype, Label* miss) { |
| 220 // Check we're still in the same context. |
| 221 __ Move(prototype, Top::global()); |
| 222 __ cmpq(Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)), |
| 223 prototype); |
| 224 __ j(not_equal, miss); |
| 220 // Get the global function with the given index. | 225 // Get the global function with the given index. |
| 221 JSFunction* function = JSFunction::cast(Top::global_context()->get(index)); | 226 JSFunction* function = JSFunction::cast(Top::global_context()->get(index)); |
| 222 // Load its initial map. The global functions all have initial maps. | 227 // Load its initial map. The global functions all have initial maps. |
| 223 __ Move(prototype, Handle<Map>(function->initial_map())); | 228 __ Move(prototype, Handle<Map>(function->initial_map())); |
| 224 // Load the prototype from the initial map. | 229 // Load the prototype from the initial map. |
| 225 __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | 230 __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); |
| 226 } | 231 } |
| 227 | 232 |
| 228 | 233 |
| 229 // Load a fast property out of a holder object (src). In-object properties | 234 // Load a fast property out of a holder object (src). In-object properties |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 case STRING_CHECK: | 911 case STRING_CHECK: |
| 907 if (!function->IsBuiltin()) { | 912 if (!function->IsBuiltin()) { |
| 908 // Calling non-builtins with a value as receiver requires boxing. | 913 // Calling non-builtins with a value as receiver requires boxing. |
| 909 __ jmp(&miss); | 914 __ jmp(&miss); |
| 910 } else { | 915 } else { |
| 911 // Check that the object is a two-byte string or a symbol. | 916 // Check that the object is a two-byte string or a symbol. |
| 912 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); | 917 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); |
| 913 __ j(above_equal, &miss); | 918 __ j(above_equal, &miss); |
| 914 // Check that the maps starting from the prototype haven't changed. | 919 // Check that the maps starting from the prototype haven't changed. |
| 915 GenerateDirectLoadGlobalFunctionPrototype( | 920 GenerateDirectLoadGlobalFunctionPrototype( |
| 916 masm(), Context::STRING_FUNCTION_INDEX, rax); | 921 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss); |
| 917 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 922 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
| 918 rbx, rdx, rdi, name, &miss); | 923 rbx, rdx, rdi, name, &miss); |
| 919 } | 924 } |
| 920 break; | 925 break; |
| 921 | 926 |
| 922 case NUMBER_CHECK: { | 927 case NUMBER_CHECK: { |
| 923 if (!function->IsBuiltin()) { | 928 if (!function->IsBuiltin()) { |
| 924 // Calling non-builtins with a value as receiver requires boxing. | 929 // Calling non-builtins with a value as receiver requires boxing. |
| 925 __ jmp(&miss); | 930 __ jmp(&miss); |
| 926 } else { | 931 } else { |
| 927 Label fast; | 932 Label fast; |
| 928 // Check that the object is a smi or a heap number. | 933 // Check that the object is a smi or a heap number. |
| 929 __ JumpIfSmi(rdx, &fast); | 934 __ JumpIfSmi(rdx, &fast); |
| 930 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax); | 935 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax); |
| 931 __ j(not_equal, &miss); | 936 __ j(not_equal, &miss); |
| 932 __ bind(&fast); | 937 __ bind(&fast); |
| 933 // Check that the maps starting from the prototype haven't changed. | 938 // Check that the maps starting from the prototype haven't changed. |
| 934 GenerateDirectLoadGlobalFunctionPrototype( | 939 GenerateDirectLoadGlobalFunctionPrototype( |
| 935 masm(), Context::NUMBER_FUNCTION_INDEX, rax); | 940 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss); |
| 936 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 941 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
| 937 rbx, rdx, rdi, name, &miss); | 942 rbx, rdx, rdi, name, &miss); |
| 938 } | 943 } |
| 939 break; | 944 break; |
| 940 } | 945 } |
| 941 | 946 |
| 942 case BOOLEAN_CHECK: { | 947 case BOOLEAN_CHECK: { |
| 943 if (!function->IsBuiltin()) { | 948 if (!function->IsBuiltin()) { |
| 944 // Calling non-builtins with a value as receiver requires boxing. | 949 // Calling non-builtins with a value as receiver requires boxing. |
| 945 __ jmp(&miss); | 950 __ jmp(&miss); |
| 946 } else { | 951 } else { |
| 947 Label fast; | 952 Label fast; |
| 948 // Check that the object is a boolean. | 953 // Check that the object is a boolean. |
| 949 __ CompareRoot(rdx, Heap::kTrueValueRootIndex); | 954 __ CompareRoot(rdx, Heap::kTrueValueRootIndex); |
| 950 __ j(equal, &fast); | 955 __ j(equal, &fast); |
| 951 __ CompareRoot(rdx, Heap::kFalseValueRootIndex); | 956 __ CompareRoot(rdx, Heap::kFalseValueRootIndex); |
| 952 __ j(not_equal, &miss); | 957 __ j(not_equal, &miss); |
| 953 __ bind(&fast); | 958 __ bind(&fast); |
| 954 // Check that the maps starting from the prototype haven't changed. | 959 // Check that the maps starting from the prototype haven't changed. |
| 955 GenerateDirectLoadGlobalFunctionPrototype( | 960 GenerateDirectLoadGlobalFunctionPrototype( |
| 956 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax); | 961 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss); |
| 957 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 962 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
| 958 rbx, rdx, rdi, name, &miss); | 963 rbx, rdx, rdi, name, &miss); |
| 959 } | 964 } |
| 960 break; | 965 break; |
| 961 } | 966 } |
| 962 | 967 |
| 963 default: | 968 default: |
| 964 UNREACHABLE(); | 969 UNREACHABLE(); |
| 965 } | 970 } |
| 966 | 971 |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 const int argc = arguments().immediate(); | 1311 const int argc = arguments().immediate(); |
| 1307 | 1312 |
| 1308 Label miss; | 1313 Label miss; |
| 1309 Label index_out_of_range; | 1314 Label index_out_of_range; |
| 1310 | 1315 |
| 1311 GenerateNameCheck(name, &miss); | 1316 GenerateNameCheck(name, &miss); |
| 1312 | 1317 |
| 1313 // Check that the maps starting from the prototype haven't changed. | 1318 // Check that the maps starting from the prototype haven't changed. |
| 1314 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1319 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 1315 Context::STRING_FUNCTION_INDEX, | 1320 Context::STRING_FUNCTION_INDEX, |
| 1316 rax); | 1321 rax, |
| 1322 &miss); |
| 1317 ASSERT(object != holder); | 1323 ASSERT(object != holder); |
| 1318 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 1324 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
| 1319 rbx, rdx, rdi, name, &miss); | 1325 rbx, rdx, rdi, name, &miss); |
| 1320 | 1326 |
| 1321 Register receiver = rax; | 1327 Register receiver = rax; |
| 1322 Register index = rdi; | 1328 Register index = rdi; |
| 1323 Register scratch1 = rbx; | 1329 Register scratch1 = rbx; |
| 1324 Register scratch2 = rdx; | 1330 Register scratch2 = rdx; |
| 1325 Register result = rax; | 1331 Register result = rax; |
| 1326 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); | 1332 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 | 1382 |
| 1377 const int argc = arguments().immediate(); | 1383 const int argc = arguments().immediate(); |
| 1378 | 1384 |
| 1379 Label miss; | 1385 Label miss; |
| 1380 Label index_out_of_range; | 1386 Label index_out_of_range; |
| 1381 GenerateNameCheck(name, &miss); | 1387 GenerateNameCheck(name, &miss); |
| 1382 | 1388 |
| 1383 // Check that the maps starting from the prototype haven't changed. | 1389 // Check that the maps starting from the prototype haven't changed. |
| 1384 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1390 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 1385 Context::STRING_FUNCTION_INDEX, | 1391 Context::STRING_FUNCTION_INDEX, |
| 1386 rax); | 1392 rax, |
| 1393 &miss); |
| 1387 ASSERT(object != holder); | 1394 ASSERT(object != holder); |
| 1388 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 1395 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
| 1389 rbx, rdx, rdi, name, &miss); | 1396 rbx, rdx, rdi, name, &miss); |
| 1390 | 1397 |
| 1391 Register receiver = rbx; | 1398 Register receiver = rbx; |
| 1392 Register index = rdi; | 1399 Register index = rdi; |
| 1393 Register scratch = rdx; | 1400 Register scratch = rdx; |
| 1394 Register result = rax; | 1401 Register result = rax; |
| 1395 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); | 1402 __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize)); |
| 1396 if (argc > 0) { | 1403 if (argc > 0) { |
| (...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2713 // Return the generated code. | 2720 // Return the generated code. |
| 2714 return GetCode(); | 2721 return GetCode(); |
| 2715 } | 2722 } |
| 2716 | 2723 |
| 2717 | 2724 |
| 2718 #undef __ | 2725 #undef __ |
| 2719 | 2726 |
| 2720 } } // namespace v8::internal | 2727 } } // namespace v8::internal |
| 2721 | 2728 |
| 2722 #endif // V8_TARGET_ARCH_X64 | 2729 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |