OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/ic/handler-compiler.h" | 7 #include "src/ic/handler-compiler.h" |
8 | 8 |
9 #include "src/api-arguments.h" | 9 #include "src/api-arguments.h" |
10 #include "src/field-type.h" | 10 #include "src/field-type.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 __ Pop(slot); | 37 __ Pop(slot); |
38 } | 38 } |
39 | 39 |
40 | 40 |
41 void PropertyHandlerCompiler::DiscardVectorAndSlot() { | 41 void PropertyHandlerCompiler::DiscardVectorAndSlot() { |
42 MacroAssembler* masm = this->masm(); | 42 MacroAssembler* masm = this->masm(); |
43 // Remove vector and slot. | 43 // Remove vector and slot. |
44 __ addp(rsp, Immediate(2 * kPointerSize)); | 44 __ addp(rsp, Immediate(2 * kPointerSize)); |
45 } | 45 } |
46 | 46 |
47 void PropertyHandlerCompiler::PushReturnAddress(Register tmp) { | |
48 MacroAssembler* masm = this->masm(); | |
49 __ Push(tmp); | |
50 } | |
51 | |
52 void PropertyHandlerCompiler::PopReturnAddress(Register tmp) { | |
53 MacroAssembler* masm = this->masm(); | |
54 __ Pop(tmp); | |
55 } | |
56 | |
57 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( | 47 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( |
58 MacroAssembler* masm, Label* miss_label, Register receiver, | 48 MacroAssembler* masm, Label* miss_label, Register receiver, |
59 Handle<Name> name, Register scratch0, Register scratch1) { | 49 Handle<Name> name, Register scratch0, Register scratch1) { |
60 DCHECK(name->IsUniqueName()); | 50 DCHECK(name->IsUniqueName()); |
61 DCHECK(!receiver.is(scratch0)); | 51 DCHECK(!receiver.is(scratch0)); |
62 Counters* counters = masm->isolate()->counters(); | 52 Counters* counters = masm->isolate()->counters(); |
63 __ IncrementCounter(counters->negative_lookups(), 1); | 53 __ IncrementCounter(counters->negative_lookups(), 1); |
64 __ IncrementCounter(counters->negative_lookups_miss(), 1); | 54 __ IncrementCounter(counters->negative_lookups_miss(), 1); |
65 | 55 |
66 __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); | 56 __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); |
(...skipping 19 matching lines...) Expand all Loading... |
86 Heap::kHashTableMapRootIndex); | 76 Heap::kHashTableMapRootIndex); |
87 __ j(not_equal, miss_label); | 77 __ j(not_equal, miss_label); |
88 | 78 |
89 Label done; | 79 Label done; |
90 NameDictionaryLookupStub::GenerateNegativeLookup(masm, miss_label, &done, | 80 NameDictionaryLookupStub::GenerateNegativeLookup(masm, miss_label, &done, |
91 properties, name, scratch1); | 81 properties, name, scratch1); |
92 __ bind(&done); | 82 __ bind(&done); |
93 __ DecrementCounter(counters->negative_lookups_miss(), 1); | 83 __ DecrementCounter(counters->negative_lookups_miss(), 1); |
94 } | 84 } |
95 | 85 |
96 | |
97 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( | |
98 MacroAssembler* masm, int index, Register result, Label* miss) { | |
99 __ LoadNativeContextSlot(index, result); | |
100 // Load its initial map. The global functions all have initial maps. | |
101 __ movp(result, | |
102 FieldOperand(result, JSFunction::kPrototypeOrInitialMapOffset)); | |
103 // Load the prototype from the initial map. | |
104 __ movp(result, FieldOperand(result, Map::kPrototypeOffset)); | |
105 } | |
106 | |
107 | |
108 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( | 86 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( |
109 MacroAssembler* masm, Register receiver, Register result, Register scratch, | 87 MacroAssembler* masm, Register receiver, Register result, Register scratch, |
110 Label* miss_label) { | 88 Label* miss_label) { |
111 __ TryGetFunctionPrototype(receiver, result, miss_label); | 89 __ TryGetFunctionPrototype(receiver, result, miss_label); |
112 if (!result.is(rax)) __ movp(rax, result); | 90 if (!result.is(rax)) __ movp(rax, result); |
113 __ ret(0); | 91 __ ret(0); |
114 } | 92 } |
115 | 93 |
116 | 94 |
117 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, | 95 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 | 319 |
342 | 320 |
343 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, | 321 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, |
344 Handle<Name> name) { | 322 Handle<Name> name) { |
345 if (!label->is_unused()) { | 323 if (!label->is_unused()) { |
346 __ bind(label); | 324 __ bind(label); |
347 __ Move(this->name(), name); | 325 __ Move(this->name(), name); |
348 } | 326 } |
349 } | 327 } |
350 | 328 |
351 | |
352 void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { | |
353 __ Move(this->name(), name); | |
354 } | |
355 | |
356 | |
357 void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition, | |
358 Register map_reg, | |
359 Register scratch, | |
360 Label* miss) { | |
361 Handle<WeakCell> cell = Map::WeakCellForMap(transition); | |
362 DCHECK(!map_reg.is(scratch)); | |
363 __ LoadWeakValue(map_reg, cell, miss); | |
364 if (transition->CanBeDeprecated()) { | |
365 __ movl(scratch, FieldOperand(map_reg, Map::kBitField3Offset)); | |
366 __ andl(scratch, Immediate(Map::Deprecated::kMask)); | |
367 __ j(not_zero, miss); | |
368 } | |
369 } | |
370 | |
371 | |
372 void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg, | |
373 int descriptor, | |
374 Register value_reg, | |
375 Register scratch, | |
376 Label* miss_label) { | |
377 DCHECK(!map_reg.is(scratch)); | |
378 DCHECK(!map_reg.is(value_reg)); | |
379 DCHECK(!value_reg.is(scratch)); | |
380 __ LoadInstanceDescriptors(map_reg, scratch); | |
381 __ movp(scratch, | |
382 FieldOperand(scratch, DescriptorArray::GetValueOffset(descriptor))); | |
383 __ cmpp(value_reg, scratch); | |
384 __ j(not_equal, miss_label); | |
385 } | |
386 | |
387 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(FieldType* field_type, | |
388 Register value_reg, | |
389 Label* miss_label) { | |
390 Register map_reg = scratch1(); | |
391 Register scratch = scratch2(); | |
392 DCHECK(!value_reg.is(map_reg)); | |
393 DCHECK(!value_reg.is(scratch)); | |
394 __ JumpIfSmi(value_reg, miss_label); | |
395 if (field_type->IsClass()) { | |
396 Label do_store; | |
397 __ movp(map_reg, FieldOperand(value_reg, HeapObject::kMapOffset)); | |
398 __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()), | |
399 scratch); | |
400 __ j(not_equal, miss_label); | |
401 } | |
402 } | |
403 | |
404 void PropertyHandlerCompiler::GenerateAccessCheck( | 329 void PropertyHandlerCompiler::GenerateAccessCheck( |
405 Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2, | 330 Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2, |
406 Label* miss, bool compare_native_contexts_only) { | 331 Label* miss, bool compare_native_contexts_only) { |
407 Label done; | 332 Label done; |
408 // Load current native context. | 333 // Load current native context. |
409 __ movp(scratch1, NativeContextOperand()); | 334 __ movp(scratch1, NativeContextOperand()); |
410 // Load expected native context. | 335 // Load expected native context. |
411 __ LoadWeakValue(scratch2, native_context_cell, miss); | 336 __ LoadWeakValue(scratch2, native_context_cell, miss); |
412 __ cmpp(scratch1, scratch2); | 337 __ cmpp(scratch1, scratch2); |
413 | 338 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 if (!miss->is_unused()) { | 451 if (!miss->is_unused()) { |
527 Label success; | 452 Label success; |
528 __ jmp(&success); | 453 __ jmp(&success); |
529 GenerateRestoreName(miss, name); | 454 GenerateRestoreName(miss, name); |
530 if (IC::ICUseVector(kind())) PopVectorAndSlot(); | 455 if (IC::ICUseVector(kind())) PopVectorAndSlot(); |
531 TailCallBuiltin(masm(), MissBuiltin(kind())); | 456 TailCallBuiltin(masm(), MissBuiltin(kind())); |
532 __ bind(&success); | 457 __ bind(&success); |
533 } | 458 } |
534 } | 459 } |
535 | 460 |
536 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { | |
537 // Return the constant value. | |
538 __ Move(rax, value); | |
539 __ ret(0); | |
540 } | |
541 | |
542 | |
543 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( | 461 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( |
544 LookupIterator* it, Register holder_reg) { | 462 LookupIterator* it, Register holder_reg) { |
545 DCHECK(holder()->HasNamedInterceptor()); | 463 DCHECK(holder()->HasNamedInterceptor()); |
546 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); | 464 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); |
547 | 465 |
548 // Compile the interceptor call, followed by inline code to load the | 466 // Compile the interceptor call, followed by inline code to load the |
549 // property from further up the prototype chain if the call fails. | 467 // property from further up the prototype chain if the call fails. |
550 // Check that the maps haven't changed. | 468 // Check that the maps haven't changed. |
551 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); | 469 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); |
552 | 470 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 // Return the generated code. | 605 // Return the generated code. |
688 return GetCode(kind(), name); | 606 return GetCode(kind(), name); |
689 } | 607 } |
690 | 608 |
691 | 609 |
692 #undef __ | 610 #undef __ |
693 } // namespace internal | 611 } // namespace internal |
694 } // namespace v8 | 612 } // namespace v8 |
695 | 613 |
696 #endif // V8_TARGET_ARCH_X64 | 614 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |