| 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 734 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   745                      Context::SECURITY_TOKEN_INDEX * kPointerSize; |   745                      Context::SECURITY_TOKEN_INDEX * kPointerSize; | 
|   746   mov(scratch, FieldOperand(scratch, token_offset)); |   746   mov(scratch, FieldOperand(scratch, token_offset)); | 
|   747   cmp(scratch, FieldOperand(holder_reg, token_offset)); |   747   cmp(scratch, FieldOperand(holder_reg, token_offset)); | 
|   748   pop(holder_reg); |   748   pop(holder_reg); | 
|   749   j(not_equal, miss); |   749   j(not_equal, miss); | 
|   750  |   750  | 
|   751   bind(&same_contexts); |   751   bind(&same_contexts); | 
|   752 } |   752 } | 
|   753  |   753  | 
|   754  |   754  | 
 |   755 // Compute the hash code from the untagged key.  This must be kept in sync | 
 |   756 // with ComputeIntegerHash in utils.h. | 
 |   757 // | 
 |   758 // Note: r0 will contain hash code | 
 |   759 void MacroAssembler::GetNumberHash(Register r0, Register scratch) { | 
 |   760   // Xor original key with a seed. | 
 |   761   if (Serializer::enabled()) { | 
 |   762     ExternalReference roots_address = | 
 |   763         ExternalReference::roots_address(isolate()); | 
 |   764     mov(scratch, Immediate(Heap::kHashSeedRootIndex)); | 
 |   765     mov(scratch, Operand::StaticArray(scratch, | 
 |   766                                       times_pointer_size, | 
 |   767                                       roots_address)); | 
 |   768     SmiUntag(scratch); | 
 |   769     xor_(r0, Operand(scratch)); | 
 |   770   } else { | 
 |   771     int32_t seed = isolate()->heap()->HashSeed(); | 
 |   772     xor_(r0, seed); | 
 |   773   } | 
 |   774  | 
 |   775   // hash = ~hash + (hash << 15); | 
 |   776   mov(scratch, r0); | 
 |   777   not_(r0); | 
 |   778   shl(scratch, 15); | 
 |   779   add(r0, Operand(scratch)); | 
 |   780   // hash = hash ^ (hash >> 12); | 
 |   781   mov(scratch, r0); | 
 |   782   shr(scratch, 12); | 
 |   783   xor_(r0, Operand(scratch)); | 
 |   784   // hash = hash + (hash << 2); | 
 |   785   lea(r0, Operand(r0, r0, times_4, 0)); | 
 |   786   // hash = hash ^ (hash >> 4); | 
 |   787   mov(scratch, r0); | 
 |   788   shr(scratch, 4); | 
 |   789   xor_(r0, Operand(scratch)); | 
 |   790   // hash = hash * 2057; | 
 |   791   imul(r0, r0, 2057); | 
 |   792   // hash = hash ^ (hash >> 16); | 
 |   793   mov(scratch, r0); | 
 |   794   shr(scratch, 16); | 
 |   795   xor_(r0, Operand(scratch)); | 
 |   796 } | 
 |   797  | 
 |   798  | 
 |   799  | 
|   755 void MacroAssembler::LoadFromNumberDictionary(Label* miss, |   800 void MacroAssembler::LoadFromNumberDictionary(Label* miss, | 
|   756                                               Register elements, |   801                                               Register elements, | 
|   757                                               Register key, |   802                                               Register key, | 
|   758                                               Register r0, |   803                                               Register r0, | 
|   759                                               Register r1, |   804                                               Register r1, | 
|   760                                               Register r2, |   805                                               Register r2, | 
|   761                                               Register result) { |   806                                               Register result) { | 
|   762   // Register use: |   807   // Register use: | 
|   763   // |   808   // | 
|   764   // elements - holds the slow-case elements of the receiver and is unchanged. |   809   // elements - holds the slow-case elements of the receiver and is unchanged. | 
|   765   // |   810   // | 
|   766   // key      - holds the smi key on entry and is unchanged. |   811   // key      - holds the smi key on entry and is unchanged. | 
|   767   // |   812   // | 
|   768   // Scratch registers: |   813   // Scratch registers: | 
|   769   // |   814   // | 
|   770   // r0 - holds the untagged key on entry and holds the hash once computed. |   815   // r0 - holds the untagged key on entry and holds the hash once computed. | 
|   771   // |   816   // | 
|   772   // r1 - used to hold the capacity mask of the dictionary |   817   // r1 - used to hold the capacity mask of the dictionary | 
|   773   // |   818   // | 
|   774   // r2 - used for the index into the dictionary. |   819   // r2 - used for the index into the dictionary. | 
|   775   // |   820   // | 
|   776   // result - holds the result on exit if the load succeeds and we fall through. |   821   // result - holds the result on exit if the load succeeds and we fall through. | 
|   777  |   822  | 
|   778   Label done; |   823   Label done; | 
|   779  |   824  | 
|   780   // Compute the hash code from the untagged key.  This must be kept in sync |   825   GetNumberHash(r0, r1); | 
|   781   // with ComputeIntegerHash in utils.h. |  | 
|   782   // |  | 
|   783   // hash = ~hash + (hash << 15); |  | 
|   784   mov(r1, r0); |  | 
|   785   not_(r0); |  | 
|   786   shl(r1, 15); |  | 
|   787   add(r0, Operand(r1)); |  | 
|   788   // hash = hash ^ (hash >> 12); |  | 
|   789   mov(r1, r0); |  | 
|   790   shr(r1, 12); |  | 
|   791   xor_(r0, Operand(r1)); |  | 
|   792   // hash = hash + (hash << 2); |  | 
|   793   lea(r0, Operand(r0, r0, times_4, 0)); |  | 
|   794   // hash = hash ^ (hash >> 4); |  | 
|   795   mov(r1, r0); |  | 
|   796   shr(r1, 4); |  | 
|   797   xor_(r0, Operand(r1)); |  | 
|   798   // hash = hash * 2057; |  | 
|   799   imul(r0, r0, 2057); |  | 
|   800   // hash = hash ^ (hash >> 16); |  | 
|   801   mov(r1, r0); |  | 
|   802   shr(r1, 16); |  | 
|   803   xor_(r0, Operand(r1)); |  | 
|   804  |   826  | 
|   805   // Compute capacity mask. |   827   // Compute capacity mask. | 
|   806   mov(r1, FieldOperand(elements, NumberDictionary::kCapacityOffset)); |   828   mov(r1, FieldOperand(elements, SeededNumberDictionary::kCapacityOffset)); | 
|   807   shr(r1, kSmiTagSize);  // convert smi to int |   829   shr(r1, kSmiTagSize);  // convert smi to int | 
|   808   dec(r1); |   830   dec(r1); | 
|   809  |   831  | 
|   810   // Generate an unrolled loop that performs a few probes before giving up. |   832   // Generate an unrolled loop that performs a few probes before giving up. | 
|   811   const int kProbes = 4; |   833   const int kProbes = 4; | 
|   812   for (int i = 0; i < kProbes; i++) { |   834   for (int i = 0; i < kProbes; i++) { | 
|   813     // Use r2 for index calculations and keep the hash intact in r0. |   835     // Use r2 for index calculations and keep the hash intact in r0. | 
|   814     mov(r2, r0); |   836     mov(r2, r0); | 
|   815     // Compute the masked index: (hash + i + i * i) & mask. |   837     // Compute the masked index: (hash + i + i * i) & mask. | 
|   816     if (i > 0) { |   838     if (i > 0) { | 
|   817       add(Operand(r2), Immediate(NumberDictionary::GetProbeOffset(i))); |   839       add(Operand(r2), Immediate(SeededNumberDictionary::GetProbeOffset(i))); | 
|   818     } |   840     } | 
|   819     and_(r2, Operand(r1)); |   841     and_(r2, Operand(r1)); | 
|   820  |   842  | 
|   821     // Scale the index by multiplying by the entry size. |   843     // Scale the index by multiplying by the entry size. | 
|   822     ASSERT(NumberDictionary::kEntrySize == 3); |   844     ASSERT(SeededNumberDictionary::kEntrySize == 3); | 
|   823     lea(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3 |   845     lea(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3 | 
|   824  |   846  | 
|   825     // Check if the key matches. |   847     // Check if the key matches. | 
|   826     cmp(key, FieldOperand(elements, |   848     cmp(key, FieldOperand(elements, | 
|   827                           r2, |   849                           r2, | 
|   828                           times_pointer_size, |   850                           times_pointer_size, | 
|   829                           NumberDictionary::kElementsStartOffset)); |   851                           SeededNumberDictionary::kElementsStartOffset)); | 
|   830     if (i != (kProbes - 1)) { |   852     if (i != (kProbes - 1)) { | 
|   831       j(equal, &done); |   853       j(equal, &done); | 
|   832     } else { |   854     } else { | 
|   833       j(not_equal, miss); |   855       j(not_equal, miss); | 
|   834     } |   856     } | 
|   835   } |   857   } | 
|   836  |   858  | 
|   837   bind(&done); |   859   bind(&done); | 
|   838   // Check that the value is a normal propety. |   860   // Check that the value is a normal propety. | 
|   839   const int kDetailsOffset = |   861   const int kDetailsOffset = | 
|   840       NumberDictionary::kElementsStartOffset + 2 * kPointerSize; |   862       SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; | 
|   841   ASSERT_EQ(NORMAL, 0); |   863   ASSERT_EQ(NORMAL, 0); | 
|   842   test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), |   864   test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), | 
|   843        Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); |   865        Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); | 
|   844   j(not_zero, miss); |   866   j(not_zero, miss); | 
|   845  |   867  | 
|   846   // Get the value at the masked, scaled index. |   868   // Get the value at the masked, scaled index. | 
|   847   const int kValueOffset = |   869   const int kValueOffset = | 
|   848       NumberDictionary::kElementsStartOffset + kPointerSize; |   870       SeededNumberDictionary::kElementsStartOffset + kPointerSize; | 
|   849   mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); |   871   mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); | 
|   850 } |   872 } | 
|   851  |   873  | 
|   852  |   874  | 
|   853 void MacroAssembler::LoadAllocationTopHelper(Register result, |   875 void MacroAssembler::LoadAllocationTopHelper(Register result, | 
|   854                                              Register scratch, |   876                                              Register scratch, | 
|   855                                              AllocationFlags flags) { |   877                                              AllocationFlags flags) { | 
|   856   ExternalReference new_space_allocation_top = |   878   ExternalReference new_space_allocation_top = | 
|   857       ExternalReference::new_space_allocation_top_address(isolate()); |   879       ExternalReference::new_space_allocation_top_address(isolate()); | 
|   858  |   880  | 
| (...skipping 1423 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2282  |  2304  | 
|  2283   // Check that the code was patched as expected. |  2305   // Check that the code was patched as expected. | 
|  2284   ASSERT(masm_.pc_ == address_ + size_); |  2306   ASSERT(masm_.pc_ == address_ + size_); | 
|  2285   ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |  2307   ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 
|  2286 } |  2308 } | 
|  2287  |  2309  | 
|  2288  |  2310  | 
|  2289 } }  // namespace v8::internal |  2311 } }  // namespace v8::internal | 
|  2290  |  2312  | 
|  2291 #endif  // V8_TARGET_ARCH_IA32 |  2313 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW |