| 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 43 | 43 | 
| 44 #define __ ACCESS_MASM(masm) | 44 #define __ ACCESS_MASM(masm) | 
| 45 | 45 | 
| 46 | 46 | 
| 47 static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm, | 47 static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm, | 
| 48                                             Register type, | 48                                             Register type, | 
| 49                                             Label* global_object) { | 49                                             Label* global_object) { | 
| 50   // Register usage: | 50   // Register usage: | 
| 51   //   type: holds the receiver instance type on entry. | 51   //   type: holds the receiver instance type on entry. | 
| 52   __ cmp(type, JS_GLOBAL_OBJECT_TYPE); | 52   __ cmp(type, JS_GLOBAL_OBJECT_TYPE); | 
| 53   __ j(equal, global_object, not_taken); | 53   __ j(equal, global_object); | 
| 54   __ cmp(type, JS_BUILTINS_OBJECT_TYPE); | 54   __ cmp(type, JS_BUILTINS_OBJECT_TYPE); | 
| 55   __ j(equal, global_object, not_taken); | 55   __ j(equal, global_object); | 
| 56   __ cmp(type, JS_GLOBAL_PROXY_TYPE); | 56   __ cmp(type, JS_GLOBAL_PROXY_TYPE); | 
| 57   __ j(equal, global_object, not_taken); | 57   __ j(equal, global_object); | 
| 58 } | 58 } | 
| 59 | 59 | 
| 60 | 60 | 
| 61 // Generated code falls through if the receiver is a regular non-global | 61 // Generated code falls through if the receiver is a regular non-global | 
| 62 // JS object with slow properties and no interceptors. | 62 // JS object with slow properties and no interceptors. | 
| 63 static void GenerateStringDictionaryReceiverCheck(MacroAssembler* masm, | 63 static void GenerateStringDictionaryReceiverCheck(MacroAssembler* masm, | 
| 64                                                   Register receiver, | 64                                                   Register receiver, | 
| 65                                                   Register r0, | 65                                                   Register r0, | 
| 66                                                   Register r1, | 66                                                   Register r1, | 
| 67                                                   Label* miss) { | 67                                                   Label* miss) { | 
| 68   // Register usage: | 68   // Register usage: | 
| 69   //   receiver: holds the receiver on entry and is unchanged. | 69   //   receiver: holds the receiver on entry and is unchanged. | 
| 70   //   r0: used to hold receiver instance type. | 70   //   r0: used to hold receiver instance type. | 
| 71   //       Holds the property dictionary on fall through. | 71   //       Holds the property dictionary on fall through. | 
| 72   //   r1: used to hold receivers map. | 72   //   r1: used to hold receivers map. | 
| 73 | 73 | 
| 74   // Check that the receiver isn't a smi. | 74   // Check that the receiver isn't a smi. | 
| 75   __ test(receiver, Immediate(kSmiTagMask)); | 75   __ test(receiver, Immediate(kSmiTagMask)); | 
| 76   __ j(zero, miss, not_taken); | 76   __ j(zero, miss); | 
| 77 | 77 | 
| 78   // Check that the receiver is a valid JS object. | 78   // Check that the receiver is a valid JS object. | 
| 79   __ mov(r1, FieldOperand(receiver, HeapObject::kMapOffset)); | 79   __ mov(r1, FieldOperand(receiver, HeapObject::kMapOffset)); | 
| 80   __ movzx_b(r0, FieldOperand(r1, Map::kInstanceTypeOffset)); | 80   __ movzx_b(r0, FieldOperand(r1, Map::kInstanceTypeOffset)); | 
| 81   __ cmp(r0, FIRST_JS_OBJECT_TYPE); | 81   __ cmp(r0, FIRST_JS_OBJECT_TYPE); | 
| 82   __ j(below, miss, not_taken); | 82   __ j(below, miss); | 
| 83 | 83 | 
| 84   // If this assert fails, we have to check upper bound too. | 84   // If this assert fails, we have to check upper bound too. | 
| 85   ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | 85   ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | 
| 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, not_taken); | 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, true); | 
| 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 | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 139   // If probing finds an entry in the dictionary, r0 contains the | 139   // If probing finds an entry in the dictionary, r0 contains the | 
| 140   // index into the dictionary. Check that the value is a normal | 140   // index into the dictionary. Check that the value is a normal | 
| 141   // property. | 141   // property. | 
| 142   __ bind(&done); | 142   __ bind(&done); | 
| 143   const int kElementsStartOffset = | 143   const int kElementsStartOffset = | 
| 144       StringDictionary::kHeaderSize + | 144       StringDictionary::kHeaderSize + | 
| 145       StringDictionary::kElementsStartIndex * kPointerSize; | 145       StringDictionary::kElementsStartIndex * kPointerSize; | 
| 146   const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; | 146   const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; | 
| 147   __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), | 147   __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), | 
| 148           Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); | 148           Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); | 
| 149   __ j(not_zero, miss_label, not_taken); | 149   __ j(not_zero, miss_label); | 
| 150 | 150 | 
| 151   // Get the value at the masked, scaled index. | 151   // Get the value at the masked, scaled index. | 
| 152   const int kValueOffset = kElementsStartOffset + kPointerSize; | 152   const int kValueOffset = kElementsStartOffset + kPointerSize; | 
| 153   __ mov(result, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); | 153   __ mov(result, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); | 
| 154 } | 154 } | 
| 155 | 155 | 
| 156 | 156 | 
| 157 // Helper function used to store a property to a dictionary backing | 157 // Helper function used to store a property to a dictionary backing | 
| 158 // storage. This function may fail to store a property eventhough it | 158 // storage. This function may fail to store a property eventhough it | 
| 159 // is in the dictionary, so code at miss_label must always call a | 159 // is in the dictionary, so code at miss_label must always call a | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 197   __ bind(&done); | 197   __ bind(&done); | 
| 198   const int kElementsStartOffset = | 198   const int kElementsStartOffset = | 
| 199       StringDictionary::kHeaderSize + | 199       StringDictionary::kHeaderSize + | 
| 200       StringDictionary::kElementsStartIndex * kPointerSize; | 200       StringDictionary::kElementsStartIndex * kPointerSize; | 
| 201   const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; | 201   const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; | 
| 202   const int kTypeAndReadOnlyMask | 202   const int kTypeAndReadOnlyMask | 
| 203       = (PropertyDetails::TypeField::mask() | | 203       = (PropertyDetails::TypeField::mask() | | 
| 204          PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; | 204          PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; | 
| 205   __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), | 205   __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), | 
| 206           Immediate(kTypeAndReadOnlyMask)); | 206           Immediate(kTypeAndReadOnlyMask)); | 
| 207   __ j(not_zero, miss_label, not_taken); | 207   __ j(not_zero, miss_label); | 
| 208 | 208 | 
| 209   // Store the value at the masked, scaled index. | 209   // Store the value at the masked, scaled index. | 
| 210   const int kValueOffset = kElementsStartOffset + kPointerSize; | 210   const int kValueOffset = kElementsStartOffset + kPointerSize; | 
| 211   __ lea(r0, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); | 211   __ lea(r0, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); | 
| 212   __ mov(Operand(r0, 0), value); | 212   __ mov(Operand(r0, 0), value); | 
| 213 | 213 | 
| 214   // Update write barrier. Make sure not to clobber the value. | 214   // Update write barrier. Make sure not to clobber the value. | 
| 215   __ mov(r1, value); | 215   __ mov(r1, value); | 
| 216   __ RecordWrite(elements, r0, r1); | 216   __ RecordWrite(elements, r0, r1); | 
| 217 } | 217 } | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 287     // Scale the index by multiplying by the entry size. | 287     // Scale the index by multiplying by the entry size. | 
| 288     ASSERT(NumberDictionary::kEntrySize == 3); | 288     ASSERT(NumberDictionary::kEntrySize == 3); | 
| 289     __ lea(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3 | 289     __ lea(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3 | 
| 290 | 290 | 
| 291     // Check if the key matches. | 291     // Check if the key matches. | 
| 292     __ cmp(key, FieldOperand(elements, | 292     __ cmp(key, FieldOperand(elements, | 
| 293                              r2, | 293                              r2, | 
| 294                              times_pointer_size, | 294                              times_pointer_size, | 
| 295                              NumberDictionary::kElementsStartOffset)); | 295                              NumberDictionary::kElementsStartOffset)); | 
| 296     if (i != (kProbes - 1)) { | 296     if (i != (kProbes - 1)) { | 
| 297       __ j(equal, &done, taken); | 297       __ j(equal, &done); | 
| 298     } else { | 298     } else { | 
| 299       __ j(not_equal, miss, not_taken); | 299       __ j(not_equal, miss); | 
| 300     } | 300     } | 
| 301   } | 301   } | 
| 302 | 302 | 
| 303   __ bind(&done); | 303   __ bind(&done); | 
| 304   // Check that the value is a normal propety. | 304   // Check that the value is a normal propety. | 
| 305   const int kDetailsOffset = | 305   const int kDetailsOffset = | 
| 306       NumberDictionary::kElementsStartOffset + 2 * kPointerSize; | 306       NumberDictionary::kElementsStartOffset + 2 * kPointerSize; | 
| 307   ASSERT_EQ(NORMAL, 0); | 307   ASSERT_EQ(NORMAL, 0); | 
| 308   __ test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), | 308   __ test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), | 
| 309           Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); | 309           Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 367                                            Register map, | 367                                            Register map, | 
| 368                                            int interceptor_bit, | 368                                            int interceptor_bit, | 
| 369                                            Label* slow) { | 369                                            Label* slow) { | 
| 370   // Register use: | 370   // Register use: | 
| 371   //   receiver - holds the receiver and is unchanged. | 371   //   receiver - holds the receiver and is unchanged. | 
| 372   // Scratch registers: | 372   // Scratch registers: | 
| 373   //   map - used to hold the map of the receiver. | 373   //   map - used to hold the map of the receiver. | 
| 374 | 374 | 
| 375   // Check that the object isn't a smi. | 375   // Check that the object isn't a smi. | 
| 376   __ test(receiver, Immediate(kSmiTagMask)); | 376   __ test(receiver, Immediate(kSmiTagMask)); | 
| 377   __ j(zero, slow, not_taken); | 377   __ j(zero, slow); | 
| 378 | 378 | 
| 379   // Get the map of the receiver. | 379   // Get the map of the receiver. | 
| 380   __ mov(map, FieldOperand(receiver, HeapObject::kMapOffset)); | 380   __ mov(map, FieldOperand(receiver, HeapObject::kMapOffset)); | 
| 381 | 381 | 
| 382   // Check bit field. | 382   // Check bit field. | 
| 383   __ test_b(FieldOperand(map, Map::kBitFieldOffset), | 383   __ test_b(FieldOperand(map, Map::kBitFieldOffset), | 
| 384             (1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)); | 384             (1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)); | 
| 385   __ j(not_zero, slow, not_taken); | 385   __ j(not_zero, slow); | 
| 386   // Check that the object is some kind of JS object EXCEPT JS Value type. | 386   // Check that the object is some kind of JS object EXCEPT JS Value type. | 
| 387   // In the case that the object is a value-wrapper object, | 387   // In the case that the object is a value-wrapper object, | 
| 388   // we enter the runtime system to make sure that indexing | 388   // we enter the runtime system to make sure that indexing | 
| 389   // into string objects works as intended. | 389   // into string objects works as intended. | 
| 390   ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); | 390   ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); | 
| 391 | 391 | 
| 392   __ CmpInstanceType(map, JS_OBJECT_TYPE); | 392   __ CmpInstanceType(map, JS_OBJECT_TYPE); | 
| 393   __ j(below, slow, not_taken); | 393   __ j(below, slow); | 
| 394 } | 394 } | 
| 395 | 395 | 
| 396 | 396 | 
| 397 // Loads an indexed element from a fast case array. | 397 // Loads an indexed element from a fast case array. | 
| 398 // If not_fast_array is NULL, doesn't perform the elements map check. | 398 // If not_fast_array is NULL, doesn't perform the elements map check. | 
| 399 static void GenerateFastArrayLoad(MacroAssembler* masm, | 399 static void GenerateFastArrayLoad(MacroAssembler* masm, | 
| 400                                   Register receiver, | 400                                   Register receiver, | 
| 401                                   Register key, | 401                                   Register key, | 
| 402                                   Register scratch, | 402                                   Register scratch, | 
| 403                                   Register result, | 403                                   Register result, | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 446   //   key - holds the key and is unchanged. Assumed to be non-smi. | 446   //   key - holds the key and is unchanged. Assumed to be non-smi. | 
| 447   // Scratch registers: | 447   // Scratch registers: | 
| 448   //   map - used to hold the map of the key. | 448   //   map - used to hold the map of the key. | 
| 449   //   hash - used to hold the hash of the key. | 449   //   hash - used to hold the hash of the key. | 
| 450   __ CmpObjectType(key, FIRST_NONSTRING_TYPE, map); | 450   __ CmpObjectType(key, FIRST_NONSTRING_TYPE, map); | 
| 451   __ j(above_equal, not_symbol); | 451   __ j(above_equal, not_symbol); | 
| 452 | 452 | 
| 453   // Is the string an array index, with cached numeric value? | 453   // Is the string an array index, with cached numeric value? | 
| 454   __ mov(hash, FieldOperand(key, String::kHashFieldOffset)); | 454   __ mov(hash, FieldOperand(key, String::kHashFieldOffset)); | 
| 455   __ test(hash, Immediate(String::kContainsCachedArrayIndexMask)); | 455   __ test(hash, Immediate(String::kContainsCachedArrayIndexMask)); | 
| 456   __ j(zero, index_string, not_taken); | 456   __ j(zero, index_string); | 
| 457 | 457 | 
| 458   // Is the string a symbol? | 458   // Is the string a symbol? | 
| 459   ASSERT(kSymbolTag != 0); | 459   ASSERT(kSymbolTag != 0); | 
| 460   __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), kIsSymbolMask); | 460   __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), kIsSymbolMask); | 
| 461   __ j(zero, not_symbol, not_taken); | 461   __ j(zero, not_symbol); | 
| 462 } | 462 } | 
| 463 | 463 | 
| 464 | 464 | 
| 465 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 465 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 
| 466   // ----------- S t a t e ------------- | 466   // ----------- S t a t e ------------- | 
| 467   //  -- eax    : key | 467   //  -- eax    : key | 
| 468   //  -- edx    : receiver | 468   //  -- edx    : receiver | 
| 469   //  -- esp[0] : return address | 469   //  -- esp[0] : return address | 
| 470   // ----------------------------------- | 470   // ----------------------------------- | 
| 471   Label slow, check_string, index_smi, index_string, property_array_property; | 471   Label slow, check_string, index_smi, index_string, property_array_property; | 
| 472   Label probe_dictionary, check_number_dictionary; | 472   Label probe_dictionary, check_number_dictionary; | 
| 473 | 473 | 
| 474   // Check that the key is a smi. | 474   // Check that the key is a smi. | 
| 475   __ test(eax, Immediate(kSmiTagMask)); | 475   __ test(eax, Immediate(kSmiTagMask)); | 
| 476   __ j(not_zero, &check_string, not_taken); | 476   __ j(not_zero, &check_string); | 
| 477   __ bind(&index_smi); | 477   __ bind(&index_smi); | 
| 478   // Now the key is known to be a smi. This place is also jumped to from | 478   // Now the key is known to be a smi. This place is also jumped to from | 
| 479   // where a numeric string is converted to a smi. | 479   // where a numeric string is converted to a smi. | 
| 480 | 480 | 
| 481   GenerateKeyedLoadReceiverCheck( | 481   GenerateKeyedLoadReceiverCheck( | 
| 482       masm, edx, ecx, Map::kHasIndexedInterceptor, &slow); | 482       masm, edx, ecx, Map::kHasIndexedInterceptor, &slow); | 
| 483 | 483 | 
| 484   // Check the "has fast elements" bit in the receiver's map which is | 484   // Check the "has fast elements" bit in the receiver's map which is | 
| 485   // now in ecx. | 485   // now in ecx. | 
| 486   __ test_b(FieldOperand(ecx, Map::kBitField2Offset), | 486   __ test_b(FieldOperand(ecx, Map::kBitField2Offset), | 
| 487             1 << Map::kHasFastElements); | 487             1 << Map::kHasFastElements); | 
| 488   __ j(zero, &check_number_dictionary, not_taken); | 488   __ j(zero, &check_number_dictionary); | 
| 489 | 489 | 
| 490   GenerateFastArrayLoad(masm, | 490   GenerateFastArrayLoad(masm, | 
| 491                         edx, | 491                         edx, | 
| 492                         eax, | 492                         eax, | 
| 493                         ecx, | 493                         ecx, | 
| 494                         eax, | 494                         eax, | 
| 495                         NULL, | 495                         NULL, | 
| 496                         &slow); | 496                         &slow); | 
| 497   Isolate* isolate = masm->isolate(); | 497   Isolate* isolate = masm->isolate(); | 
| 498   Counters* counters = isolate->counters(); | 498   Counters* counters = isolate->counters(); | 
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 656 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 656 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 
| 657   // ----------- S t a t e ------------- | 657   // ----------- S t a t e ------------- | 
| 658   //  -- eax    : key | 658   //  -- eax    : key | 
| 659   //  -- edx    : receiver | 659   //  -- edx    : receiver | 
| 660   //  -- esp[0] : return address | 660   //  -- esp[0] : return address | 
| 661   // ----------------------------------- | 661   // ----------------------------------- | 
| 662   Label slow; | 662   Label slow; | 
| 663 | 663 | 
| 664   // Check that the receiver isn't a smi. | 664   // Check that the receiver isn't a smi. | 
| 665   __ test(edx, Immediate(kSmiTagMask)); | 665   __ test(edx, Immediate(kSmiTagMask)); | 
| 666   __ j(zero, &slow, not_taken); | 666   __ j(zero, &slow); | 
| 667 | 667 | 
| 668   // Check that the key is an array index, that is Uint32. | 668   // Check that the key is an array index, that is Uint32. | 
| 669   __ test(eax, Immediate(kSmiTagMask | kSmiSignMask)); | 669   __ test(eax, Immediate(kSmiTagMask | kSmiSignMask)); | 
| 670   __ j(not_zero, &slow, not_taken); | 670   __ j(not_zero, &slow); | 
| 671 | 671 | 
| 672   // Get the map of the receiver. | 672   // Get the map of the receiver. | 
| 673   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 673   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 
| 674 | 674 | 
| 675   // Check that it has indexed interceptor and access checks | 675   // Check that it has indexed interceptor and access checks | 
| 676   // are not enabled for this object. | 676   // are not enabled for this object. | 
| 677   __ movzx_b(ecx, FieldOperand(ecx, Map::kBitFieldOffset)); | 677   __ movzx_b(ecx, FieldOperand(ecx, Map::kBitFieldOffset)); | 
| 678   __ and_(Operand(ecx), Immediate(kSlowCaseBitFieldMask)); | 678   __ and_(Operand(ecx), Immediate(kSlowCaseBitFieldMask)); | 
| 679   __ cmp(Operand(ecx), Immediate(1 << Map::kHasIndexedInterceptor)); | 679   __ cmp(Operand(ecx), Immediate(1 << Map::kHasIndexedInterceptor)); | 
| 680   __ j(not_zero, &slow, not_taken); | 680   __ j(not_zero, &slow); | 
| 681 | 681 | 
| 682   // Everything is fine, call runtime. | 682   // Everything is fine, call runtime. | 
| 683   __ pop(ecx); | 683   __ pop(ecx); | 
| 684   __ push(edx);  // receiver | 684   __ push(edx);  // receiver | 
| 685   __ push(eax);  // key | 685   __ push(eax);  // key | 
| 686   __ push(ecx);  // return address | 686   __ push(ecx);  // return address | 
| 687 | 687 | 
| 688   // Perform tail call to the entry. | 688   // Perform tail call to the entry. | 
| 689   ExternalReference ref = | 689   ExternalReference ref = | 
| 690       ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), | 690       ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor), | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 701   // ----------- S t a t e ------------- | 701   // ----------- S t a t e ------------- | 
| 702   //  -- eax    : value | 702   //  -- eax    : value | 
| 703   //  -- ecx    : key | 703   //  -- ecx    : key | 
| 704   //  -- edx    : receiver | 704   //  -- edx    : receiver | 
| 705   //  -- esp[0] : return address | 705   //  -- esp[0] : return address | 
| 706   // ----------------------------------- | 706   // ----------------------------------- | 
| 707   Label slow, fast, array, extra; | 707   Label slow, fast, array, extra; | 
| 708 | 708 | 
| 709   // Check that the object isn't a smi. | 709   // Check that the object isn't a smi. | 
| 710   __ test(edx, Immediate(kSmiTagMask)); | 710   __ test(edx, Immediate(kSmiTagMask)); | 
| 711   __ j(zero, &slow, not_taken); | 711   __ j(zero, &slow); | 
| 712   // Get the map from the receiver. | 712   // Get the map from the receiver. | 
| 713   __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); | 713   __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); | 
| 714   // Check that the receiver does not require access checks.  We need | 714   // Check that the receiver does not require access checks.  We need | 
| 715   // to do this because this generic stub does not perform map checks. | 715   // to do this because this generic stub does not perform map checks. | 
| 716   __ test_b(FieldOperand(edi, Map::kBitFieldOffset), | 716   __ test_b(FieldOperand(edi, Map::kBitFieldOffset), | 
| 717             1 << Map::kIsAccessCheckNeeded); | 717             1 << Map::kIsAccessCheckNeeded); | 
| 718   __ j(not_zero, &slow, not_taken); | 718   __ j(not_zero, &slow); | 
| 719   // Check that the key is a smi. | 719   // Check that the key is a smi. | 
| 720   __ test(ecx, Immediate(kSmiTagMask)); | 720   __ test(ecx, Immediate(kSmiTagMask)); | 
| 721   __ j(not_zero, &slow, not_taken); | 721   __ j(not_zero, &slow); | 
| 722   __ CmpInstanceType(edi, JS_ARRAY_TYPE); | 722   __ CmpInstanceType(edi, JS_ARRAY_TYPE); | 
| 723   __ j(equal, &array); | 723   __ j(equal, &array); | 
| 724   // Check that the object is some kind of JS object. | 724   // Check that the object is some kind of JS object. | 
| 725   __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); | 725   __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); | 
| 726   __ j(below, &slow, not_taken); | 726   __ j(below, &slow); | 
| 727 | 727 | 
| 728   // Object case: Check key against length in the elements array. | 728   // Object case: Check key against length in the elements array. | 
| 729   // eax: value | 729   // eax: value | 
| 730   // edx: JSObject | 730   // edx: JSObject | 
| 731   // ecx: key (a smi) | 731   // ecx: key (a smi) | 
| 732   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 732   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 
| 733   // Check that the object is in fast mode and writable. | 733   // Check that the object is in fast mode and writable. | 
| 734   __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, true); | 734   __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, true); | 
| 735   __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); | 735   __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); | 
| 736   __ j(below, &fast, taken); | 736   __ j(below, &fast); | 
| 737 | 737 | 
| 738   // Slow case: call runtime. | 738   // Slow case: call runtime. | 
| 739   __ bind(&slow); | 739   __ bind(&slow); | 
| 740   GenerateRuntimeSetProperty(masm, strict_mode); | 740   GenerateRuntimeSetProperty(masm, strict_mode); | 
| 741 | 741 | 
| 742   // Extra capacity case: Check if there is extra capacity to | 742   // Extra capacity case: Check if there is extra capacity to | 
| 743   // perform the store and update the length. Used for adding one | 743   // perform the store and update the length. Used for adding one | 
| 744   // element to the array by writing to array[array.length]. | 744   // element to the array by writing to array[array.length]. | 
| 745   __ bind(&extra); | 745   __ bind(&extra); | 
| 746   // eax: value | 746   // eax: value | 
| 747   // edx: receiver, a JSArray | 747   // edx: receiver, a JSArray | 
| 748   // ecx: key, a smi. | 748   // ecx: key, a smi. | 
| 749   // edi: receiver->elements, a FixedArray | 749   // edi: receiver->elements, a FixedArray | 
| 750   // flags: compare (ecx, edx.length()) | 750   // flags: compare (ecx, edx.length()) | 
| 751   // do not leave holes in the array: | 751   // do not leave holes in the array: | 
| 752   __ j(not_equal, &slow, not_taken); | 752   __ j(not_equal, &slow); | 
| 753   __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); | 753   __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); | 
| 754   __ j(above_equal, &slow, not_taken); | 754   __ j(above_equal, &slow); | 
| 755   // Add 1 to receiver->length, and go to fast array write. | 755   // Add 1 to receiver->length, and go to fast array write. | 
| 756   __ add(FieldOperand(edx, JSArray::kLengthOffset), | 756   __ add(FieldOperand(edx, JSArray::kLengthOffset), | 
| 757          Immediate(Smi::FromInt(1))); | 757          Immediate(Smi::FromInt(1))); | 
| 758   __ jmp(&fast); | 758   __ jmp(&fast); | 
| 759 | 759 | 
| 760   // Array case: Get the length and the elements array from the JS | 760   // 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 | 761   // array. Check that the array is in fast mode (and writable); if it | 
| 762   // is the length is always a smi. | 762   // is the length is always a smi. | 
| 763   __ bind(&array); | 763   __ bind(&array); | 
| 764   // eax: value | 764   // eax: value | 
| 765   // edx: receiver, a JSArray | 765   // edx: receiver, a JSArray | 
| 766   // ecx: key, a smi. | 766   // ecx: key, a smi. | 
| 767   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 767   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 
| 768   __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, true); | 768   __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, true); | 
| 769 | 769 | 
| 770   // Check the key against the length in the array, compute the | 770   // Check the key against the length in the array, compute the | 
| 771   // address to store into and fall through to fast case. | 771   // address to store into and fall through to fast case. | 
| 772   __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset));  // Compare smis. | 772   __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset));  // Compare smis. | 
| 773   __ j(above_equal, &extra, not_taken); | 773   __ j(above_equal, &extra); | 
| 774 | 774 | 
| 775   // Fast case: Do the store. | 775   // Fast case: Do the store. | 
| 776   __ bind(&fast); | 776   __ bind(&fast); | 
| 777   // eax: value | 777   // eax: value | 
| 778   // ecx: key (a smi) | 778   // ecx: key (a smi) | 
| 779   // edx: receiver | 779   // edx: receiver | 
| 780   // edi: FixedArray receiver->elements | 780   // edi: FixedArray receiver->elements | 
| 781   __ mov(CodeGenerator::FixedArrayElementOperand(edi, ecx), eax); | 781   __ mov(CodeGenerator::FixedArrayElementOperand(edi, ecx), eax); | 
| 782   // Update write barrier for the elements array address. | 782   // Update write barrier for the elements array address. | 
| 783   __ mov(edx, Operand(eax)); | 783   __ mov(edx, Operand(eax)); | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 807   Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, | 807   Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, | 
| 808                                                   eax); | 808                                                   eax); | 
| 809 | 809 | 
| 810   // If the stub cache probing failed, the receiver might be a value. | 810   // If the stub cache probing failed, the receiver might be a value. | 
| 811   // For value objects, we use the map of the prototype objects for | 811   // For value objects, we use the map of the prototype objects for | 
| 812   // the corresponding JSValue for the cache and that is what we need | 812   // the corresponding JSValue for the cache and that is what we need | 
| 813   // to probe. | 813   // to probe. | 
| 814   // | 814   // | 
| 815   // Check for number. | 815   // Check for number. | 
| 816   __ test(edx, Immediate(kSmiTagMask)); | 816   __ test(edx, Immediate(kSmiTagMask)); | 
| 817   __ j(zero, &number, not_taken); | 817   __ j(zero, &number); | 
| 818   __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ebx); | 818   __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ebx); | 
| 819   __ j(not_equal, &non_number, taken); | 819   __ j(not_equal, &non_number); | 
| 820   __ bind(&number); | 820   __ bind(&number); | 
| 821   StubCompiler::GenerateLoadGlobalFunctionPrototype( | 821   StubCompiler::GenerateLoadGlobalFunctionPrototype( | 
| 822       masm, Context::NUMBER_FUNCTION_INDEX, edx); | 822       masm, Context::NUMBER_FUNCTION_INDEX, edx); | 
| 823   __ jmp(&probe); | 823   __ jmp(&probe); | 
| 824 | 824 | 
| 825   // Check for string. | 825   // Check for string. | 
| 826   __ bind(&non_number); | 826   __ bind(&non_number); | 
| 827   __ CmpInstanceType(ebx, FIRST_NONSTRING_TYPE); | 827   __ CmpInstanceType(ebx, FIRST_NONSTRING_TYPE); | 
| 828   __ j(above_equal, &non_string, taken); | 828   __ j(above_equal, &non_string); | 
| 829   StubCompiler::GenerateLoadGlobalFunctionPrototype( | 829   StubCompiler::GenerateLoadGlobalFunctionPrototype( | 
| 830       masm, Context::STRING_FUNCTION_INDEX, edx); | 830       masm, Context::STRING_FUNCTION_INDEX, edx); | 
| 831   __ jmp(&probe); | 831   __ jmp(&probe); | 
| 832 | 832 | 
| 833   // Check for boolean. | 833   // Check for boolean. | 
| 834   __ bind(&non_string); | 834   __ bind(&non_string); | 
| 835   __ cmp(edx, FACTORY->true_value()); | 835   __ cmp(edx, FACTORY->true_value()); | 
| 836   __ j(equal, &boolean, not_taken); | 836   __ j(equal, &boolean); | 
| 837   __ cmp(edx, FACTORY->false_value()); | 837   __ cmp(edx, FACTORY->false_value()); | 
| 838   __ j(not_equal, &miss, taken); | 838   __ j(not_equal, &miss); | 
| 839   __ bind(&boolean); | 839   __ bind(&boolean); | 
| 840   StubCompiler::GenerateLoadGlobalFunctionPrototype( | 840   StubCompiler::GenerateLoadGlobalFunctionPrototype( | 
| 841       masm, Context::BOOLEAN_FUNCTION_INDEX, edx); | 841       masm, Context::BOOLEAN_FUNCTION_INDEX, edx); | 
| 842 | 842 | 
| 843   // Probe the stub cache for the value object. | 843   // Probe the stub cache for the value object. | 
| 844   __ bind(&probe); | 844   __ bind(&probe); | 
| 845   Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, | 845   Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, | 
| 846                                                   no_reg); | 846                                                   no_reg); | 
| 847   __ bind(&miss); | 847   __ bind(&miss); | 
| 848 } | 848 } | 
| 849 | 849 | 
| 850 | 850 | 
| 851 static void GenerateFunctionTailCall(MacroAssembler* masm, | 851 static void GenerateFunctionTailCall(MacroAssembler* masm, | 
| 852                                      int argc, | 852                                      int argc, | 
| 853                                      Label* miss) { | 853                                      Label* miss) { | 
| 854   // ----------- S t a t e ------------- | 854   // ----------- S t a t e ------------- | 
| 855   //  -- ecx                 : name | 855   //  -- ecx                 : name | 
| 856   //  -- edi                 : function | 856   //  -- edi                 : function | 
| 857   //  -- esp[0]              : return address | 857   //  -- esp[0]              : return address | 
| 858   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 858   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 
| 859   //  -- ... | 859   //  -- ... | 
| 860   //  -- esp[(argc + 1) * 4] : receiver | 860   //  -- esp[(argc + 1) * 4] : receiver | 
| 861   // ----------------------------------- | 861   // ----------------------------------- | 
| 862 | 862 | 
| 863   // Check that the result is not a smi. | 863   // Check that the result is not a smi. | 
| 864   __ test(edi, Immediate(kSmiTagMask)); | 864   __ test(edi, Immediate(kSmiTagMask)); | 
| 865   __ j(zero, miss, not_taken); | 865   __ j(zero, miss); | 
| 866 | 866 | 
| 867   // Check that the value is a JavaScript function, fetching its map into eax. | 867   // Check that the value is a JavaScript function, fetching its map into eax. | 
| 868   __ CmpObjectType(edi, JS_FUNCTION_TYPE, eax); | 868   __ CmpObjectType(edi, JS_FUNCTION_TYPE, eax); | 
| 869   __ j(not_equal, miss, not_taken); | 869   __ j(not_equal, miss); | 
| 870 | 870 | 
| 871   // Invoke the function. | 871   // Invoke the function. | 
| 872   ParameterCount actual(argc); | 872   ParameterCount actual(argc); | 
| 873   __ InvokeFunction(edi, actual, JUMP_FUNCTION); | 873   __ InvokeFunction(edi, actual, JUMP_FUNCTION); | 
| 874 } | 874 } | 
| 875 | 875 | 
| 876 // The generated code falls through if the call should be handled by runtime. | 876 // The generated code falls through if the call should be handled by runtime. | 
| 877 static void GenerateCallNormal(MacroAssembler* masm, int argc) { | 877 static void GenerateCallNormal(MacroAssembler* masm, int argc) { | 
| 878   // ----------- S t a t e ------------- | 878   // ----------- S t a t e ------------- | 
| 879   //  -- ecx                 : name | 879   //  -- ecx                 : name | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 935   // Move result to edi and exit the internal frame. | 935   // Move result to edi and exit the internal frame. | 
| 936   __ mov(edi, eax); | 936   __ mov(edi, eax); | 
| 937   __ LeaveInternalFrame(); | 937   __ LeaveInternalFrame(); | 
| 938 | 938 | 
| 939   // Check if the receiver is a global object of some sort. | 939   // Check if the receiver is a global object of some sort. | 
| 940   // This can happen only for regular CallIC but not KeyedCallIC. | 940   // This can happen only for regular CallIC but not KeyedCallIC. | 
| 941   if (id == IC::kCallIC_Miss) { | 941   if (id == IC::kCallIC_Miss) { | 
| 942     Label invoke, global; | 942     Label invoke, global; | 
| 943     __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));  // receiver | 943     __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));  // receiver | 
| 944     __ test(edx, Immediate(kSmiTagMask)); | 944     __ test(edx, Immediate(kSmiTagMask)); | 
| 945     __ j(zero, &invoke, not_taken, Label::kNear); | 945     __ j(zero, &invoke, Label::kNear); | 
| 946     __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); | 946     __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); | 
| 947     __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 947     __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 
| 948     __ cmp(ebx, JS_GLOBAL_OBJECT_TYPE); | 948     __ cmp(ebx, JS_GLOBAL_OBJECT_TYPE); | 
| 949     __ j(equal, &global, Label::kNear); | 949     __ j(equal, &global, Label::kNear); | 
| 950     __ cmp(ebx, JS_BUILTINS_OBJECT_TYPE); | 950     __ cmp(ebx, JS_BUILTINS_OBJECT_TYPE); | 
| 951     __ j(not_equal, &invoke, Label::kNear); | 951     __ j(not_equal, &invoke, Label::kNear); | 
| 952 | 952 | 
| 953     // Patch the receiver on the stack. | 953     // Patch the receiver on the stack. | 
| 954     __ bind(&global); | 954     __ bind(&global); | 
| 955     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 955     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1017 | 1017 | 
| 1018   // Get the receiver of the function from the stack; 1 ~ return address. | 1018   // Get the receiver of the function from the stack; 1 ~ return address. | 
| 1019   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1019   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 
| 1020 | 1020 | 
| 1021   Label do_call, slow_call, slow_load, slow_reload_receiver; | 1021   Label do_call, slow_call, slow_load, slow_reload_receiver; | 
| 1022   Label check_number_dictionary, check_string, lookup_monomorphic_cache; | 1022   Label check_number_dictionary, check_string, lookup_monomorphic_cache; | 
| 1023   Label index_smi, index_string; | 1023   Label index_smi, index_string; | 
| 1024 | 1024 | 
| 1025   // Check that the key is a smi. | 1025   // Check that the key is a smi. | 
| 1026   __ test(ecx, Immediate(kSmiTagMask)); | 1026   __ test(ecx, Immediate(kSmiTagMask)); | 
| 1027   __ j(not_zero, &check_string, not_taken); | 1027   __ j(not_zero, &check_string); | 
| 1028 | 1028 | 
| 1029   __ bind(&index_smi); | 1029   __ bind(&index_smi); | 
| 1030   // Now the key is known to be a smi. This place is also jumped to from | 1030   // Now the key is known to be a smi. This place is also jumped to from | 
| 1031   // where a numeric string is converted to a smi. | 1031   // where a numeric string is converted to a smi. | 
| 1032 | 1032 | 
| 1033   GenerateKeyedLoadReceiverCheck( | 1033   GenerateKeyedLoadReceiverCheck( | 
| 1034       masm, edx, eax, Map::kHasIndexedInterceptor, &slow_call); | 1034       masm, edx, eax, Map::kHasIndexedInterceptor, &slow_call); | 
| 1035 | 1035 | 
| 1036   GenerateFastArrayLoad( | 1036   GenerateFastArrayLoad( | 
| 1037       masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load); | 1037       masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load); | 
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1307   // Value must be a number, but only smis are accepted as the most common case. | 1307   // Value must be a number, but only smis are accepted as the most common case. | 
| 1308 | 1308 | 
| 1309   Label miss; | 1309   Label miss; | 
| 1310 | 1310 | 
| 1311   Register receiver = edx; | 1311   Register receiver = edx; | 
| 1312   Register value = eax; | 1312   Register value = eax; | 
| 1313   Register scratch = ebx; | 1313   Register scratch = ebx; | 
| 1314 | 1314 | 
| 1315   // Check that the receiver isn't a smi. | 1315   // Check that the receiver isn't a smi. | 
| 1316   __ test(receiver, Immediate(kSmiTagMask)); | 1316   __ test(receiver, Immediate(kSmiTagMask)); | 
| 1317   __ j(zero, &miss, not_taken); | 1317   __ j(zero, &miss); | 
| 1318 | 1318 | 
| 1319   // Check that the object is a JS array. | 1319   // Check that the object is a JS array. | 
| 1320   __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); | 1320   __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); | 
| 1321   __ j(not_equal, &miss, not_taken); | 1321   __ j(not_equal, &miss); | 
| 1322 | 1322 | 
| 1323   // Check that elements are FixedArray. | 1323   // Check that elements are FixedArray. | 
| 1324   // We rely on StoreIC_ArrayLength below to deal with all types of | 1324   // We rely on StoreIC_ArrayLength below to deal with all types of | 
| 1325   // fast elements (including COW). | 1325   // fast elements (including COW). | 
| 1326   __ mov(scratch, FieldOperand(receiver, JSArray::kElementsOffset)); | 1326   __ mov(scratch, FieldOperand(receiver, JSArray::kElementsOffset)); | 
| 1327   __ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch); | 1327   __ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch); | 
| 1328   __ j(not_equal, &miss, not_taken); | 1328   __ j(not_equal, &miss); | 
| 1329 | 1329 | 
| 1330   // Check that value is a smi. | 1330   // Check that value is a smi. | 
| 1331   __ test(value, Immediate(kSmiTagMask)); | 1331   __ test(value, Immediate(kSmiTagMask)); | 
| 1332   __ j(not_zero, &miss, not_taken); | 1332   __ j(not_zero, &miss); | 
| 1333 | 1333 | 
| 1334   // Prepare tail call to StoreIC_ArrayLength. | 1334   // Prepare tail call to StoreIC_ArrayLength. | 
| 1335   __ pop(scratch); | 1335   __ pop(scratch); | 
| 1336   __ push(receiver); | 1336   __ push(receiver); | 
| 1337   __ push(value); | 1337   __ push(value); | 
| 1338   __ push(scratch);  // return address | 1338   __ push(scratch);  // return address | 
| 1339 | 1339 | 
| 1340   ExternalReference ref = | 1340   ExternalReference ref = | 
| 1341       ExternalReference(IC_Utility(kStoreIC_ArrayLength), masm->isolate()); | 1341       ExternalReference(IC_Utility(kStoreIC_ArrayLength), masm->isolate()); | 
| 1342   __ TailCallExternalReference(ref, 2, 1); | 1342   __ TailCallExternalReference(ref, 2, 1); | 
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1538   Condition cc = *jmp_address == Assembler::kJncShortOpcode | 1538   Condition cc = *jmp_address == Assembler::kJncShortOpcode | 
| 1539       ? not_zero | 1539       ? not_zero | 
| 1540       : zero; | 1540       : zero; | 
| 1541   *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1541   *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 
| 1542 } | 1542 } | 
| 1543 | 1543 | 
| 1544 | 1544 | 
| 1545 } }  // namespace v8::internal | 1545 } }  // namespace v8::internal | 
| 1546 | 1546 | 
| 1547 #endif  // V8_TARGET_ARCH_IA32 | 1547 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|