| OLD | NEW | 
|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 86 | 86 | 
| 87   GenerateGlobalInstanceTypeCheck(masm, r0, miss); | 87   GenerateGlobalInstanceTypeCheck(masm, r0, miss); | 
| 88 | 88 | 
| 89   // Check for non-global object that requires access check. | 89   // Check for non-global object that requires access check. | 
| 90   __ test_b(FieldOperand(r1, Map::kBitFieldOffset), | 90   __ test_b(FieldOperand(r1, Map::kBitFieldOffset), | 
| 91             (1 << Map::kIsAccessCheckNeeded) | | 91             (1 << Map::kIsAccessCheckNeeded) | | 
| 92             (1 << Map::kHasNamedInterceptor)); | 92             (1 << Map::kHasNamedInterceptor)); | 
| 93   __ j(not_zero, miss); | 93   __ j(not_zero, miss); | 
| 94 | 94 | 
| 95   __ mov(r0, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 95   __ mov(r0, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 
| 96   __ CheckMap(r0, FACTORY->hash_table_map(), miss, true); | 96   __ CheckMap(r0, FACTORY->hash_table_map(), miss, DONT_DO_SMI_CHECK); | 
| 97 } | 97 } | 
| 98 | 98 | 
| 99 | 99 | 
| 100 // Helper function used to load a property from a dictionary backing | 100 // Helper function used to load a property from a dictionary backing | 
| 101 // storage. This function may fail to load a property even though it is | 101 // storage. This function may fail to load a property even though it is | 
| 102 // in the dictionary, so code at miss_label must always call a backup | 102 // in the dictionary, so code at miss_label must always call a backup | 
| 103 // property load that is complete. This function is safe to call if | 103 // property load that is complete. This function is safe to call if | 
| 104 // name is not a symbol, and will jump to the miss_label in that | 104 // name is not a symbol, and will jump to the miss_label in that | 
| 105 // case. The generated code assumes that the receiver has slow | 105 // case. The generated code assumes that the receiver has slow | 
| 106 // properties, is not a global object and does not have interceptors. | 106 // properties, is not a global object and does not have interceptors. | 
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 407   //   receiver - holds the receiver and is unchanged. | 407   //   receiver - holds the receiver and is unchanged. | 
| 408   //   key - holds the key and is unchanged (must be a smi). | 408   //   key - holds the key and is unchanged (must be a smi). | 
| 409   // Scratch registers: | 409   // Scratch registers: | 
| 410   //   scratch - used to hold elements of the receiver and the loaded value. | 410   //   scratch - used to hold elements of the receiver and the loaded value. | 
| 411   //   result - holds the result on exit if the load succeeds and | 411   //   result - holds the result on exit if the load succeeds and | 
| 412   //            we fall through. | 412   //            we fall through. | 
| 413 | 413 | 
| 414   __ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset)); | 414   __ mov(scratch, FieldOperand(receiver, JSObject::kElementsOffset)); | 
| 415   if (not_fast_array != NULL) { | 415   if (not_fast_array != NULL) { | 
| 416     // Check that the object is in fast mode and writable. | 416     // Check that the object is in fast mode and writable. | 
| 417     __ CheckMap(scratch, FACTORY->fixed_array_map(), not_fast_array, true); | 417     __ CheckMap(scratch, | 
|  | 418                 FACTORY->fixed_array_map(), | 
|  | 419                 not_fast_array, | 
|  | 420                 DONT_DO_SMI_CHECK); | 
| 418   } else { | 421   } else { | 
| 419     __ AssertFastElements(scratch); | 422     __ AssertFastElements(scratch); | 
| 420   } | 423   } | 
| 421   // Check that the key (index) is within bounds. | 424   // Check that the key (index) is within bounds. | 
| 422   __ cmp(key, FieldOperand(scratch, FixedArray::kLengthOffset)); | 425   __ cmp(key, FieldOperand(scratch, FixedArray::kLengthOffset)); | 
| 423   __ j(above_equal, out_of_range); | 426   __ j(above_equal, out_of_range); | 
| 424   // Fast case: Do the load. | 427   // Fast case: Do the load. | 
| 425   ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0)); | 428   ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0)); | 
| 426   __ mov(scratch, FieldOperand(scratch, key, times_2, FixedArray::kHeaderSize)); | 429   __ mov(scratch, FieldOperand(scratch, key, times_2, FixedArray::kHeaderSize)); | 
| 427   __ cmp(Operand(scratch), Immediate(FACTORY->the_hole_value())); | 430   __ cmp(Operand(scratch), Immediate(FACTORY->the_hole_value())); | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 502   __ bind(&check_number_dictionary); | 505   __ bind(&check_number_dictionary); | 
| 503   __ mov(ebx, eax); | 506   __ mov(ebx, eax); | 
| 504   __ SmiUntag(ebx); | 507   __ SmiUntag(ebx); | 
| 505   __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); | 508   __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); | 
| 506 | 509 | 
| 507   // Check whether the elements is a number dictionary. | 510   // Check whether the elements is a number dictionary. | 
| 508   // edx: receiver | 511   // edx: receiver | 
| 509   // ebx: untagged index | 512   // ebx: untagged index | 
| 510   // eax: key | 513   // eax: key | 
| 511   // ecx: elements | 514   // ecx: elements | 
| 512   __ CheckMap(ecx, isolate->factory()->hash_table_map(), &slow, true); | 515   __ CheckMap(ecx, | 
|  | 516               isolate->factory()->hash_table_map(), | 
|  | 517               &slow, | 
|  | 518               DONT_DO_SMI_CHECK); | 
| 513   Label slow_pop_receiver; | 519   Label slow_pop_receiver; | 
| 514   // Push receiver on the stack to free up a register for the dictionary | 520   // Push receiver on the stack to free up a register for the dictionary | 
| 515   // probing. | 521   // probing. | 
| 516   __ push(edx); | 522   __ push(edx); | 
| 517   GenerateNumberDictionaryLoad(masm, | 523   GenerateNumberDictionaryLoad(masm, | 
| 518                                &slow_pop_receiver, | 524                                &slow_pop_receiver, | 
| 519                                ecx, | 525                                ecx, | 
| 520                                eax, | 526                                eax, | 
| 521                                ebx, | 527                                ebx, | 
| 522                                edx, | 528                                edx, | 
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 724   // Check that the object is some kind of JS object. | 730   // Check that the object is some kind of JS object. | 
| 725   __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); | 731   __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); | 
| 726   __ j(below, &slow); | 732   __ j(below, &slow); | 
| 727 | 733 | 
| 728   // Object case: Check key against length in the elements array. | 734   // Object case: Check key against length in the elements array. | 
| 729   // eax: value | 735   // eax: value | 
| 730   // edx: JSObject | 736   // edx: JSObject | 
| 731   // ecx: key (a smi) | 737   // ecx: key (a smi) | 
| 732   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 738   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 
| 733   // Check that the object is in fast mode and writable. | 739   // Check that the object is in fast mode and writable. | 
| 734   __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, true); | 740   __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, DONT_DO_SMI_CHECK); | 
| 735   __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); | 741   __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); | 
| 736   __ j(below, &fast); | 742   __ j(below, &fast); | 
| 737 | 743 | 
| 738   // Slow case: call runtime. | 744   // Slow case: call runtime. | 
| 739   __ bind(&slow); | 745   __ bind(&slow); | 
| 740   GenerateRuntimeSetProperty(masm, strict_mode); | 746   GenerateRuntimeSetProperty(masm, strict_mode); | 
| 741 | 747 | 
| 742   // Extra capacity case: Check if there is extra capacity to | 748   // Extra capacity case: Check if there is extra capacity to | 
| 743   // perform the store and update the length. Used for adding one | 749   // perform the store and update the length. Used for adding one | 
| 744   // element to the array by writing to array[array.length]. | 750   // element to the array by writing to array[array.length]. | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 758   __ jmp(&fast); | 764   __ jmp(&fast); | 
| 759 | 765 | 
| 760   // Array case: Get the length and the elements array from the JS | 766   // Array case: Get the length and the elements array from the JS | 
| 761   // array. Check that the array is in fast mode (and writable); if it | 767   // array. Check that the array is in fast mode (and writable); if it | 
| 762   // is the length is always a smi. | 768   // is the length is always a smi. | 
| 763   __ bind(&array); | 769   __ bind(&array); | 
| 764   // eax: value | 770   // eax: value | 
| 765   // edx: receiver, a JSArray | 771   // edx: receiver, a JSArray | 
| 766   // ecx: key, a smi. | 772   // ecx: key, a smi. | 
| 767   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 773   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 
| 768   __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, true); | 774   __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, DONT_DO_SMI_CHECK); | 
| 769 | 775 | 
| 770   // Check the key against the length in the array, compute the | 776   // Check the key against the length in the array, compute the | 
| 771   // address to store into and fall through to fast case. | 777   // address to store into and fall through to fast case. | 
| 772   __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset));  // Compare smis. | 778   __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset));  // Compare smis. | 
| 773   __ j(above_equal, &extra); | 779   __ j(above_equal, &extra); | 
| 774 | 780 | 
| 775   // Fast case: Do the store. | 781   // Fast case: Do the store. | 
| 776   __ bind(&fast); | 782   __ bind(&fast); | 
| 777   // eax: value | 783   // eax: value | 
| 778   // ecx: key (a smi) | 784   // ecx: key (a smi) | 
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1042   __ bind(&do_call); | 1048   __ bind(&do_call); | 
| 1043   // receiver in edx is not used after this point. | 1049   // receiver in edx is not used after this point. | 
| 1044   // ecx: key | 1050   // ecx: key | 
| 1045   // edi: function | 1051   // edi: function | 
| 1046   GenerateFunctionTailCall(masm, argc, &slow_call); | 1052   GenerateFunctionTailCall(masm, argc, &slow_call); | 
| 1047 | 1053 | 
| 1048   __ bind(&check_number_dictionary); | 1054   __ bind(&check_number_dictionary); | 
| 1049   // eax: elements | 1055   // eax: elements | 
| 1050   // ecx: smi key | 1056   // ecx: smi key | 
| 1051   // Check whether the elements is a number dictionary. | 1057   // Check whether the elements is a number dictionary. | 
| 1052   __ CheckMap(eax, isolate->factory()->hash_table_map(), &slow_load, true); | 1058   __ CheckMap(eax, | 
|  | 1059               isolate->factory()->hash_table_map(), | 
|  | 1060               &slow_load, | 
|  | 1061               DONT_DO_SMI_CHECK); | 
| 1053   __ mov(ebx, ecx); | 1062   __ mov(ebx, ecx); | 
| 1054   __ SmiUntag(ebx); | 1063   __ SmiUntag(ebx); | 
| 1055   // ebx: untagged index | 1064   // ebx: untagged index | 
| 1056   // Receiver in edx will be clobbered, need to reload it on miss. | 1065   // Receiver in edx will be clobbered, need to reload it on miss. | 
| 1057   GenerateNumberDictionaryLoad( | 1066   GenerateNumberDictionaryLoad( | 
| 1058       masm, &slow_reload_receiver, eax, ecx, ebx, edx, edi, edi); | 1067       masm, &slow_reload_receiver, eax, ecx, ebx, edx, edi, edi); | 
| 1059   __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1); | 1068   __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1); | 
| 1060   __ jmp(&do_call); | 1069   __ jmp(&do_call); | 
| 1061 | 1070 | 
| 1062   __ bind(&slow_reload_receiver); | 1071   __ bind(&slow_reload_receiver); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 1083   // If the receiver is a regular JS object with slow properties then do | 1092   // If the receiver is a regular JS object with slow properties then do | 
| 1084   // a quick inline probe of the receiver's dictionary. | 1093   // a quick inline probe of the receiver's dictionary. | 
| 1085   // Otherwise do the monomorphic cache probe. | 1094   // Otherwise do the monomorphic cache probe. | 
| 1086   GenerateKeyedLoadReceiverCheck( | 1095   GenerateKeyedLoadReceiverCheck( | 
| 1087       masm, edx, eax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); | 1096       masm, edx, eax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); | 
| 1088 | 1097 | 
| 1089   __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset)); | 1098   __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset)); | 
| 1090   __ CheckMap(ebx, | 1099   __ CheckMap(ebx, | 
| 1091               isolate->factory()->hash_table_map(), | 1100               isolate->factory()->hash_table_map(), | 
| 1092               &lookup_monomorphic_cache, | 1101               &lookup_monomorphic_cache, | 
| 1093               true); | 1102               DONT_DO_SMI_CHECK); | 
| 1094 | 1103 | 
| 1095   GenerateDictionaryLoad(masm, &slow_load, ebx, ecx, eax, edi, edi); | 1104   GenerateDictionaryLoad(masm, &slow_load, ebx, ecx, eax, edi, edi); | 
| 1096   __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1); | 1105   __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1); | 
| 1097   __ jmp(&do_call); | 1106   __ jmp(&do_call); | 
| 1098 | 1107 | 
| 1099   __ bind(&lookup_monomorphic_cache); | 1108   __ bind(&lookup_monomorphic_cache); | 
| 1100   __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1); | 1109   __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1); | 
| 1101   GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); | 1110   GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); | 
| 1102   // Fall through on miss. | 1111   // Fall through on miss. | 
| 1103 | 1112 | 
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1538   Condition cc = *jmp_address == Assembler::kJncShortOpcode | 1547   Condition cc = *jmp_address == Assembler::kJncShortOpcode | 
| 1539       ? not_zero | 1548       ? not_zero | 
| 1540       : zero; | 1549       : zero; | 
| 1541   *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1550   *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 
| 1542 } | 1551 } | 
| 1543 | 1552 | 
| 1544 | 1553 | 
| 1545 } }  // namespace v8::internal | 1554 } }  // namespace v8::internal | 
| 1546 | 1555 | 
| 1547 #endif  // V8_TARGET_ARCH_IA32 | 1556 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|