| 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 4132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4143 __ movzxbl(result_, FieldOperand(object_, | 4143 __ movzxbl(result_, FieldOperand(object_, |
| 4144 scratch_, times_1, | 4144 scratch_, times_1, |
| 4145 SeqAsciiString::kHeaderSize)); | 4145 SeqAsciiString::kHeaderSize)); |
| 4146 __ bind(&got_char_code); | 4146 __ bind(&got_char_code); |
| 4147 __ Integer32ToSmi(result_, result_); | 4147 __ Integer32ToSmi(result_, result_); |
| 4148 __ bind(&exit_); | 4148 __ bind(&exit_); |
| 4149 } | 4149 } |
| 4150 | 4150 |
| 4151 | 4151 |
| 4152 void StringCharCodeAtGenerator::GenerateSlow( | 4152 void StringCharCodeAtGenerator::GenerateSlow( |
| 4153 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { | 4153 MacroAssembler* masm, |
| 4154 const RuntimeCallHelper& call_helper) { |
| 4154 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); | 4155 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); |
| 4155 | 4156 |
| 4156 Factory* factory = masm->isolate()->factory(); | 4157 Factory* factory = masm->isolate()->factory(); |
| 4157 // Index is not a smi. | 4158 // Index is not a smi. |
| 4158 __ bind(&index_not_smi_); | 4159 __ bind(&index_not_smi_); |
| 4159 // If index is a heap number, try converting it to an integer. | 4160 // If index is a heap number, try converting it to an integer. |
| 4160 __ CheckMap(index_, | 4161 __ CheckMap(index_, |
| 4161 factory->heap_number_map(), | 4162 factory->heap_number_map(), |
| 4162 index_not_number_, | 4163 index_not_number_, |
| 4163 DONT_DO_SMI_CHECK); | 4164 DONT_DO_SMI_CHECK); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4219 SmiIndex index = masm->SmiToIndex(kScratchRegister, code_, kPointerSizeLog2); | 4220 SmiIndex index = masm->SmiToIndex(kScratchRegister, code_, kPointerSizeLog2); |
| 4220 __ movq(result_, FieldOperand(result_, index.reg, index.scale, | 4221 __ movq(result_, FieldOperand(result_, index.reg, index.scale, |
| 4221 FixedArray::kHeaderSize)); | 4222 FixedArray::kHeaderSize)); |
| 4222 __ CompareRoot(result_, Heap::kUndefinedValueRootIndex); | 4223 __ CompareRoot(result_, Heap::kUndefinedValueRootIndex); |
| 4223 __ j(equal, &slow_case_); | 4224 __ j(equal, &slow_case_); |
| 4224 __ bind(&exit_); | 4225 __ bind(&exit_); |
| 4225 } | 4226 } |
| 4226 | 4227 |
| 4227 | 4228 |
| 4228 void StringCharFromCodeGenerator::GenerateSlow( | 4229 void StringCharFromCodeGenerator::GenerateSlow( |
| 4229 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { | 4230 MacroAssembler* masm, |
| 4231 const RuntimeCallHelper& call_helper) { |
| 4230 __ Abort("Unexpected fallthrough to CharFromCode slow case"); | 4232 __ Abort("Unexpected fallthrough to CharFromCode slow case"); |
| 4231 | 4233 |
| 4232 __ bind(&slow_case_); | 4234 __ bind(&slow_case_); |
| 4233 call_helper.BeforeCall(masm); | 4235 call_helper.BeforeCall(masm); |
| 4234 __ push(code_); | 4236 __ push(code_); |
| 4235 __ CallRuntime(Runtime::kCharFromCode, 1); | 4237 __ CallRuntime(Runtime::kCharFromCode, 1); |
| 4236 if (!result_.is(rax)) { | 4238 if (!result_.is(rax)) { |
| 4237 __ movq(result_, rax); | 4239 __ movq(result_, rax); |
| 4238 } | 4240 } |
| 4239 call_helper.AfterCall(masm); | 4241 call_helper.AfterCall(masm); |
| 4240 __ jmp(&exit_); | 4242 __ jmp(&exit_); |
| 4241 | 4243 |
| 4242 __ Abort("Unexpected fallthrough from CharFromCode slow case"); | 4244 __ Abort("Unexpected fallthrough from CharFromCode slow case"); |
| 4243 } | 4245 } |
| 4244 | 4246 |
| 4245 | 4247 |
| 4246 // ------------------------------------------------------------------------- | 4248 // ------------------------------------------------------------------------- |
| 4247 // StringCharAtGenerator | 4249 // StringCharAtGenerator |
| 4248 | 4250 |
| 4249 void StringCharAtGenerator::GenerateFast(MacroAssembler* masm) { | 4251 void StringCharAtGenerator::GenerateFast(MacroAssembler* masm) { |
| 4250 char_code_at_generator_.GenerateFast(masm); | 4252 char_code_at_generator_.GenerateFast(masm); |
| 4251 char_from_code_generator_.GenerateFast(masm); | 4253 char_from_code_generator_.GenerateFast(masm); |
| 4252 } | 4254 } |
| 4253 | 4255 |
| 4254 | 4256 |
| 4255 void StringCharAtGenerator::GenerateSlow( | 4257 void StringCharAtGenerator::GenerateSlow( |
| 4256 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { | 4258 MacroAssembler* masm, |
| 4259 const RuntimeCallHelper& call_helper) { |
| 4257 char_code_at_generator_.GenerateSlow(masm, call_helper); | 4260 char_code_at_generator_.GenerateSlow(masm, call_helper); |
| 4258 char_from_code_generator_.GenerateSlow(masm, call_helper); | 4261 char_from_code_generator_.GenerateSlow(masm, call_helper); |
| 4259 } | 4262 } |
| 4260 | 4263 |
| 4261 | 4264 |
| 4262 void StringAddStub::Generate(MacroAssembler* masm) { | 4265 void StringAddStub::Generate(MacroAssembler* masm) { |
| 4263 Label string_add_runtime, call_builtin; | 4266 Label string_add_runtime, call_builtin; |
| 4264 Builtins::JavaScript builtin_id = Builtins::ADD; | 4267 Builtins::JavaScript builtin_id = Builtins::ADD; |
| 4265 | 4268 |
| 4266 // Load the two arguments. | 4269 // Load the two arguments. |
| (...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5513 StringDictionaryLookupStub::NEGATIVE_LOOKUP); | 5516 StringDictionaryLookupStub::NEGATIVE_LOOKUP); |
| 5514 __ Push(Handle<Object>(name)); | 5517 __ Push(Handle<Object>(name)); |
| 5515 __ push(Immediate(name->Hash())); | 5518 __ push(Immediate(name->Hash())); |
| 5516 __ CallStub(&stub); | 5519 __ CallStub(&stub); |
| 5517 __ testq(r0, r0); | 5520 __ testq(r0, r0); |
| 5518 __ j(not_zero, miss); | 5521 __ j(not_zero, miss); |
| 5519 __ jmp(done); | 5522 __ jmp(done); |
| 5520 } | 5523 } |
| 5521 | 5524 |
| 5522 | 5525 |
| 5523 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
| 5524 // handlified. | |
| 5525 MaybeObject* StringDictionaryLookupStub::TryGenerateNegativeLookup( | |
| 5526 MacroAssembler* masm, | |
| 5527 Label* miss, | |
| 5528 Label* done, | |
| 5529 Register properties, | |
| 5530 String* name, | |
| 5531 Register r0) { | |
| 5532 // If names of slots in range from 1 to kProbes - 1 for the hash value are | |
| 5533 // not equal to the name and kProbes-th slot is not used (its name is the | |
| 5534 // undefined value), it guarantees the hash table doesn't contain the | |
| 5535 // property. It's true even if some slots represent deleted properties | |
| 5536 // (their names are the null value). | |
| 5537 for (int i = 0; i < kInlinedProbes; i++) { | |
| 5538 // r0 points to properties hash. | |
| 5539 // Compute the masked index: (hash + i + i * i) & mask. | |
| 5540 Register index = r0; | |
| 5541 // Capacity is smi 2^n. | |
| 5542 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset)); | |
| 5543 __ decl(index); | |
| 5544 __ and_(index, | |
| 5545 Immediate(name->Hash() + StringDictionary::GetProbeOffset(i))); | |
| 5546 | |
| 5547 // Scale the index by multiplying by the entry size. | |
| 5548 ASSERT(StringDictionary::kEntrySize == 3); | |
| 5549 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. | |
| 5550 | |
| 5551 Register entity_name = r0; | |
| 5552 // Having undefined at this place means the name is not contained. | |
| 5553 ASSERT_EQ(kSmiTagSize, 1); | |
| 5554 __ movq(entity_name, Operand(properties, | |
| 5555 index, | |
| 5556 times_pointer_size, | |
| 5557 kElementsStartOffset - kHeapObjectTag)); | |
| 5558 __ Cmp(entity_name, masm->isolate()->factory()->undefined_value()); | |
| 5559 __ j(equal, done); | |
| 5560 | |
| 5561 // Stop if found the property. | |
| 5562 __ Cmp(entity_name, Handle<String>(name)); | |
| 5563 __ j(equal, miss); | |
| 5564 | |
| 5565 // Check if the entry name is not a symbol. | |
| 5566 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); | |
| 5567 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), | |
| 5568 Immediate(kIsSymbolMask)); | |
| 5569 __ j(zero, miss); | |
| 5570 } | |
| 5571 | |
| 5572 StringDictionaryLookupStub stub(properties, | |
| 5573 r0, | |
| 5574 r0, | |
| 5575 StringDictionaryLookupStub::NEGATIVE_LOOKUP); | |
| 5576 __ Push(Handle<Object>(name)); | |
| 5577 __ push(Immediate(name->Hash())); | |
| 5578 MaybeObject* result = masm->TryCallStub(&stub); | |
| 5579 if (result->IsFailure()) return result; | |
| 5580 __ testq(r0, r0); | |
| 5581 __ j(not_zero, miss); | |
| 5582 __ jmp(done); | |
| 5583 return result; | |
| 5584 } | |
| 5585 | |
| 5586 | |
| 5587 // Probe the string dictionary in the |elements| register. Jump to the | 5526 // Probe the string dictionary in the |elements| register. Jump to the |
| 5588 // |done| label if a property with the given name is found leaving the | 5527 // |done| label if a property with the given name is found leaving the |
| 5589 // index into the dictionary in |r1|. Jump to the |miss| label | 5528 // index into the dictionary in |r1|. Jump to the |miss| label |
| 5590 // otherwise. | 5529 // otherwise. |
| 5591 void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, | 5530 void StringDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, |
| 5592 Label* miss, | 5531 Label* miss, |
| 5593 Label* done, | 5532 Label* done, |
| 5594 Register elements, | 5533 Register elements, |
| 5595 Register name, | 5534 Register name, |
| 5596 Register r0, | 5535 Register r0, |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6003 __ bind(&need_incremental); | 5942 __ bind(&need_incremental); |
| 6004 | 5943 |
| 6005 // Fall through when we need to inform the incremental marker. | 5944 // Fall through when we need to inform the incremental marker. |
| 6006 } | 5945 } |
| 6007 | 5946 |
| 6008 #undef __ | 5947 #undef __ |
| 6009 | 5948 |
| 6010 } } // namespace v8::internal | 5949 } } // namespace v8::internal |
| 6011 | 5950 |
| 6012 #endif // V8_TARGET_ARCH_X64 | 5951 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |