Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/regexp-macro-assembler-x64.cc ('k') | src/x87/assembler-x87.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 10 matching lines...) Expand all
21 MacroAssembler* masm, 21 MacroAssembler* masm,
22 Code::Flags flags, 22 Code::Flags flags,
23 StubCache::Table table, 23 StubCache::Table table,
24 Register receiver, 24 Register receiver,
25 Register name, 25 Register name,
26 // The offset is scaled by 4, based on 26 // The offset is scaled by 4, based on
27 // kCacheIndexShift, which is two bits 27 // kCacheIndexShift, which is two bits
28 Register offset) { 28 Register offset) {
29 // We need to scale up the pointer by 2 when the offset is scaled by less 29 // We need to scale up the pointer by 2 when the offset is scaled by less
30 // than the pointer size. 30 // than the pointer size.
31 ASSERT(kPointerSize == kInt64Size 31 DCHECK(kPointerSize == kInt64Size
32 ? kPointerSizeLog2 == StubCache::kCacheIndexShift + 1 32 ? kPointerSizeLog2 == StubCache::kCacheIndexShift + 1
33 : kPointerSizeLog2 == StubCache::kCacheIndexShift); 33 : kPointerSizeLog2 == StubCache::kCacheIndexShift);
34 ScaleFactor scale_factor = kPointerSize == kInt64Size ? times_2 : times_1; 34 ScaleFactor scale_factor = kPointerSize == kInt64Size ? times_2 : times_1;
35 35
36 ASSERT_EQ(3 * kPointerSize, sizeof(StubCache::Entry)); 36 DCHECK_EQ(3 * kPointerSize, sizeof(StubCache::Entry));
37 // The offset register holds the entry offset times four (due to masking 37 // The offset register holds the entry offset times four (due to masking
38 // and shifting optimizations). 38 // and shifting optimizations).
39 ExternalReference key_offset(isolate->stub_cache()->key_reference(table)); 39 ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
40 ExternalReference value_offset(isolate->stub_cache()->value_reference(table)); 40 ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
41 Label miss; 41 Label miss;
42 42
43 // Multiply by 3 because there are 3 fields per entry (name, code, map). 43 // Multiply by 3 because there are 3 fields per entry (name, code, map).
44 __ leap(offset, Operand(offset, offset, times_2, 0)); 44 __ leap(offset, Operand(offset, offset, times_2, 0));
45 45
46 __ LoadAddress(kScratchRegister, key_offset); 46 __ LoadAddress(kScratchRegister, key_offset);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 __ addp(kScratchRegister, Immediate(Code::kHeaderSize - kHeapObjectTag)); 82 __ addp(kScratchRegister, Immediate(Code::kHeaderSize - kHeapObjectTag));
83 __ jmp(kScratchRegister); 83 __ jmp(kScratchRegister);
84 84
85 __ bind(&miss); 85 __ bind(&miss);
86 } 86 }
87 87
88 88
89 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 89 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
90 MacroAssembler* masm, Label* miss_label, Register receiver, 90 MacroAssembler* masm, Label* miss_label, Register receiver,
91 Handle<Name> name, Register scratch0, Register scratch1) { 91 Handle<Name> name, Register scratch0, Register scratch1) {
92 ASSERT(name->IsUniqueName()); 92 DCHECK(name->IsUniqueName());
93 ASSERT(!receiver.is(scratch0)); 93 DCHECK(!receiver.is(scratch0));
94 Counters* counters = masm->isolate()->counters(); 94 Counters* counters = masm->isolate()->counters();
95 __ IncrementCounter(counters->negative_lookups(), 1); 95 __ IncrementCounter(counters->negative_lookups(), 1);
96 __ IncrementCounter(counters->negative_lookups_miss(), 1); 96 __ IncrementCounter(counters->negative_lookups_miss(), 1);
97 97
98 __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); 98 __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
99 99
100 const int kInterceptorOrAccessCheckNeededMask = 100 const int kInterceptorOrAccessCheckNeededMask =
101 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 101 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
102 102
103 // Bail out if the receiver has a named interceptor or requires access checks. 103 // Bail out if the receiver has a named interceptor or requires access checks.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 Register extra, 138 Register extra,
139 Register extra2, 139 Register extra2,
140 Register extra3) { 140 Register extra3) {
141 Isolate* isolate = masm->isolate(); 141 Isolate* isolate = masm->isolate();
142 Label miss; 142 Label miss;
143 USE(extra); // The register extra is not used on the X64 platform. 143 USE(extra); // The register extra is not used on the X64 platform.
144 USE(extra2); // The register extra2 is not used on the X64 platform. 144 USE(extra2); // The register extra2 is not used on the X64 platform.
145 USE(extra3); // The register extra2 is not used on the X64 platform. 145 USE(extra3); // The register extra2 is not used on the X64 platform.
146 // Make sure that code is valid. The multiplying code relies on the 146 // Make sure that code is valid. The multiplying code relies on the
147 // entry size being 3 * kPointerSize. 147 // entry size being 3 * kPointerSize.
148 ASSERT(sizeof(Entry) == 3 * kPointerSize); 148 DCHECK(sizeof(Entry) == 3 * kPointerSize);
149 149
150 // Make sure the flags do not name a specific type. 150 // Make sure the flags do not name a specific type.
151 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); 151 DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
152 152
153 // Make sure that there are no register conflicts. 153 // Make sure that there are no register conflicts.
154 ASSERT(!scratch.is(receiver)); 154 DCHECK(!scratch.is(receiver));
155 ASSERT(!scratch.is(name)); 155 DCHECK(!scratch.is(name));
156 156
157 // Check scratch register is valid, extra and extra2 are unused. 157 // Check scratch register is valid, extra and extra2 are unused.
158 ASSERT(!scratch.is(no_reg)); 158 DCHECK(!scratch.is(no_reg));
159 ASSERT(extra2.is(no_reg)); 159 DCHECK(extra2.is(no_reg));
160 ASSERT(extra3.is(no_reg)); 160 DCHECK(extra3.is(no_reg));
161 161
162 Counters* counters = masm->isolate()->counters(); 162 Counters* counters = masm->isolate()->counters();
163 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); 163 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1);
164 164
165 // Check that the receiver isn't a smi. 165 // Check that the receiver isn't a smi.
166 __ JumpIfSmi(receiver, &miss); 166 __ JumpIfSmi(receiver, &miss);
167 167
168 // Get the map of the receiver and compute the hash. 168 // Get the map of the receiver and compute the hash.
169 __ movl(scratch, FieldOperand(name, Name::kHashFieldOffset)); 169 __ movl(scratch, FieldOperand(name, Name::kHashFieldOffset));
170 // Use only the low 32 bits of the map pointer. 170 // Use only the low 32 bits of the map pointer.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 Register holder, 232 Register holder,
233 Register name, 233 Register name,
234 Handle<JSObject> holder_obj) { 234 Handle<JSObject> holder_obj) {
235 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 235 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
236 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); 236 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
237 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); 237 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
238 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); 238 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
239 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4); 239 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
240 __ Push(name); 240 __ Push(name);
241 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); 241 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
242 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); 242 DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
243 __ Move(kScratchRegister, interceptor); 243 __ Move(kScratchRegister, interceptor);
244 __ Push(kScratchRegister); 244 __ Push(kScratchRegister);
245 __ Push(receiver); 245 __ Push(receiver);
246 __ Push(holder); 246 __ Push(holder);
247 } 247 }
248 248
249 249
250 static void CompileCallLoadPropertyWithInterceptor( 250 static void CompileCallLoadPropertyWithInterceptor(
251 MacroAssembler* masm, 251 MacroAssembler* masm,
252 Register receiver, 252 Register receiver,
253 Register holder, 253 Register holder,
254 Register name, 254 Register name,
255 Handle<JSObject> holder_obj, 255 Handle<JSObject> holder_obj,
256 IC::UtilityId id) { 256 IC::UtilityId id) {
257 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 257 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
258 __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), 258 __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
259 NamedLoadHandlerCompiler::kInterceptorArgsLength); 259 NamedLoadHandlerCompiler::kInterceptorArgsLength);
260 } 260 }
261 261
262 262
263 // Generate call to api function. 263 // Generate call to api function.
264 void PropertyHandlerCompiler::GenerateFastApiCall( 264 void PropertyHandlerCompiler::GenerateFastApiCall(
265 MacroAssembler* masm, const CallOptimization& optimization, 265 MacroAssembler* masm, const CallOptimization& optimization,
266 Handle<Map> receiver_map, Register receiver, Register scratch_in, 266 Handle<Map> receiver_map, Register receiver, Register scratch_in,
267 bool is_store, int argc, Register* values) { 267 bool is_store, int argc, Register* values) {
268 ASSERT(optimization.is_simple_api_call()); 268 DCHECK(optimization.is_simple_api_call());
269 269
270 __ PopReturnAddressTo(scratch_in); 270 __ PopReturnAddressTo(scratch_in);
271 // receiver 271 // receiver
272 __ Push(receiver); 272 __ Push(receiver);
273 // Write the arguments to stack frame. 273 // Write the arguments to stack frame.
274 for (int i = 0; i < argc; i++) { 274 for (int i = 0; i < argc; i++) {
275 Register arg = values[argc-1-i]; 275 Register arg = values[argc-1-i];
276 ASSERT(!receiver.is(arg)); 276 DCHECK(!receiver.is(arg));
277 ASSERT(!scratch_in.is(arg)); 277 DCHECK(!scratch_in.is(arg));
278 __ Push(arg); 278 __ Push(arg);
279 } 279 }
280 __ PushReturnAddressFrom(scratch_in); 280 __ PushReturnAddressFrom(scratch_in);
281 // Stack now matches JSFunction abi. 281 // Stack now matches JSFunction abi.
282 282
283 // Abi for CallApiFunctionStub. 283 // Abi for CallApiFunctionStub.
284 Register callee = rax; 284 Register callee = rax;
285 Register call_data = rbx; 285 Register call_data = rbx;
286 Register holder = rcx; 286 Register holder = rcx;
287 Register api_function_address = rdx; 287 Register api_function_address = rdx;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 333 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
334 __ TailCallStub(&stub); 334 __ TailCallStub(&stub);
335 } 335 }
336 336
337 337
338 void PropertyHandlerCompiler::GenerateCheckPropertyCell( 338 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
339 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 339 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
340 Register scratch, Label* miss) { 340 Register scratch, Label* miss) {
341 Handle<PropertyCell> cell = 341 Handle<PropertyCell> cell =
342 JSGlobalObject::EnsurePropertyCell(global, name); 342 JSGlobalObject::EnsurePropertyCell(global, name);
343 ASSERT(cell->value()->IsTheHole()); 343 DCHECK(cell->value()->IsTheHole());
344 __ Move(scratch, cell); 344 __ Move(scratch, cell);
345 __ Cmp(FieldOperand(scratch, Cell::kValueOffset), 345 __ Cmp(FieldOperand(scratch, Cell::kValueOffset),
346 masm->isolate()->factory()->the_hole_value()); 346 masm->isolate()->factory()->the_hole_value());
347 __ j(not_equal, miss); 347 __ j(not_equal, miss);
348 } 348 }
349 349
350 350
351 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm, 351 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
352 Handle<Code> code) { 352 Handle<Code> code) {
353 __ jmp(code, RelocInfo::CODE_TARGET); 353 __ jmp(code, RelocInfo::CODE_TARGET);
(...skipping 16 matching lines...) Expand all
370 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 370 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
371 // store is successful. 371 // store is successful.
372 void NamedStoreHandlerCompiler::GenerateStoreTransition( 372 void NamedStoreHandlerCompiler::GenerateStoreTransition(
373 Handle<Map> transition, Handle<Name> name, Register receiver_reg, 373 Handle<Map> transition, Handle<Name> name, Register receiver_reg,
374 Register storage_reg, Register value_reg, Register scratch1, 374 Register storage_reg, Register value_reg, Register scratch1,
375 Register scratch2, Register unused, Label* miss_label, Label* slow) { 375 Register scratch2, Register unused, Label* miss_label, Label* slow) {
376 int descriptor = transition->LastAdded(); 376 int descriptor = transition->LastAdded();
377 DescriptorArray* descriptors = transition->instance_descriptors(); 377 DescriptorArray* descriptors = transition->instance_descriptors();
378 PropertyDetails details = descriptors->GetDetails(descriptor); 378 PropertyDetails details = descriptors->GetDetails(descriptor);
379 Representation representation = details.representation(); 379 Representation representation = details.representation();
380 ASSERT(!representation.IsNone()); 380 DCHECK(!representation.IsNone());
381 381
382 if (details.type() == CONSTANT) { 382 if (details.type() == CONSTANT) {
383 Handle<Object> constant(descriptors->GetValue(descriptor), isolate()); 383 Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
384 __ Cmp(value_reg, constant); 384 __ Cmp(value_reg, constant);
385 __ j(not_equal, miss_label); 385 __ j(not_equal, miss_label);
386 } else if (representation.IsSmi()) { 386 } else if (representation.IsSmi()) {
387 __ JumpIfNotSmi(value_reg, miss_label); 387 __ JumpIfNotSmi(value_reg, miss_label);
388 } else if (representation.IsHeapObject()) { 388 } else if (representation.IsHeapObject()) {
389 __ JumpIfSmi(value_reg, miss_label); 389 __ JumpIfSmi(value_reg, miss_label);
390 HeapType* field_type = descriptors->GetFieldType(descriptor); 390 HeapType* field_type = descriptors->GetFieldType(descriptor);
(...skipping 23 matching lines...) Expand all
414 __ bind(&heap_number); 414 __ bind(&heap_number);
415 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label, 415 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
416 DONT_DO_SMI_CHECK); 416 DONT_DO_SMI_CHECK);
417 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 417 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
418 418
419 __ bind(&do_store); 419 __ bind(&do_store);
420 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 420 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
421 } 421 }
422 422
423 // Stub never generated for objects that require access checks. 423 // Stub never generated for objects that require access checks.
424 ASSERT(!transition->is_access_check_needed()); 424 DCHECK(!transition->is_access_check_needed());
425 425
426 // Perform map transition for the receiver if necessary. 426 // Perform map transition for the receiver if necessary.
427 if (details.type() == FIELD && 427 if (details.type() == FIELD &&
428 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) { 428 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
429 // The properties must be extended before we can store the value. 429 // The properties must be extended before we can store the value.
430 // We jump to a runtime call that extends the properties array. 430 // We jump to a runtime call that extends the properties array.
431 __ PopReturnAddressTo(scratch1); 431 __ PopReturnAddressTo(scratch1);
432 __ Push(receiver_reg); 432 __ Push(receiver_reg);
433 __ Push(transition); 433 __ Push(transition);
434 __ Push(value_reg); 434 __ Push(value_reg);
(...skipping 12 matching lines...) Expand all
447 // Update the write barrier for the map field. 447 // Update the write barrier for the map field.
448 __ RecordWriteField(receiver_reg, 448 __ RecordWriteField(receiver_reg,
449 HeapObject::kMapOffset, 449 HeapObject::kMapOffset,
450 scratch1, 450 scratch1,
451 scratch2, 451 scratch2,
452 kDontSaveFPRegs, 452 kDontSaveFPRegs,
453 OMIT_REMEMBERED_SET, 453 OMIT_REMEMBERED_SET,
454 OMIT_SMI_CHECK); 454 OMIT_SMI_CHECK);
455 455
456 if (details.type() == CONSTANT) { 456 if (details.type() == CONSTANT) {
457 ASSERT(value_reg.is(rax)); 457 DCHECK(value_reg.is(rax));
458 __ ret(0); 458 __ ret(0);
459 return; 459 return;
460 } 460 }
461 461
462 int index = transition->instance_descriptors()->GetFieldIndex( 462 int index = transition->instance_descriptors()->GetFieldIndex(
463 transition->LastAdded()); 463 transition->LastAdded());
464 464
465 // Adjust for the number of properties stored in the object. Even in the 465 // Adjust for the number of properties stored in the object. Even in the
466 // face of a transition we can use the old map here because the size of the 466 // face of a transition we can use the old map here because the size of the
467 // object and the number of in-object properties is not going to change. 467 // object and the number of in-object properties is not going to change.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 if (!representation.IsDouble()) { 504 if (!representation.IsDouble()) {
505 __ movp(storage_reg, value_reg); 505 __ movp(storage_reg, value_reg);
506 } 506 }
507 __ RecordWriteField( 507 __ RecordWriteField(
508 scratch1, offset, storage_reg, receiver_reg, kDontSaveFPRegs, 508 scratch1, offset, storage_reg, receiver_reg, kDontSaveFPRegs,
509 EMIT_REMEMBERED_SET, smi_check); 509 EMIT_REMEMBERED_SET, smi_check);
510 } 510 }
511 } 511 }
512 512
513 // Return the value (register rax). 513 // Return the value (register rax).
514 ASSERT(value_reg.is(rax)); 514 DCHECK(value_reg.is(rax));
515 __ ret(0); 515 __ ret(0);
516 } 516 }
517 517
518 518
519 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 519 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
520 // but may be destroyed if store is successful. 520 // but may be destroyed if store is successful.
521 void NamedStoreHandlerCompiler::GenerateStoreField( 521 void NamedStoreHandlerCompiler::GenerateStoreField(
522 Handle<JSObject> object, LookupResult* lookup, Register receiver_reg, 522 Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
523 Register name_reg, Register value_reg, Register scratch1, Register scratch2, 523 Register name_reg, Register value_reg, Register scratch1, Register scratch2,
524 Label* miss_label) { 524 Label* miss_label) {
525 // Stub never generated for objects that require access checks. 525 // Stub never generated for objects that require access checks.
526 ASSERT(!object->IsAccessCheckNeeded()); 526 DCHECK(!object->IsAccessCheckNeeded());
527 ASSERT(!object->IsJSGlobalProxy()); 527 DCHECK(!object->IsJSGlobalProxy());
528 528
529 FieldIndex index = lookup->GetFieldIndex(); 529 FieldIndex index = lookup->GetFieldIndex();
530 530
531 Representation representation = lookup->representation(); 531 Representation representation = lookup->representation();
532 ASSERT(!representation.IsNone()); 532 DCHECK(!representation.IsNone());
533 if (representation.IsSmi()) { 533 if (representation.IsSmi()) {
534 __ JumpIfNotSmi(value_reg, miss_label); 534 __ JumpIfNotSmi(value_reg, miss_label);
535 } else if (representation.IsHeapObject()) { 535 } else if (representation.IsHeapObject()) {
536 __ JumpIfSmi(value_reg, miss_label); 536 __ JumpIfSmi(value_reg, miss_label);
537 HeapType* field_type = lookup->GetFieldType(); 537 HeapType* field_type = lookup->GetFieldType();
538 HeapType::Iterator<Map> it = field_type->Classes(); 538 HeapType::Iterator<Map> it = field_type->Classes();
539 if (!it.Done()) { 539 if (!it.Done()) {
540 Label do_store; 540 Label do_store;
541 while (true) { 541 while (true) {
542 __ CompareMap(value_reg, it.Current()); 542 __ CompareMap(value_reg, it.Current());
(...skipping 23 matching lines...) Expand all
566 __ Cvtlsi2sd(xmm0, scratch2); 566 __ Cvtlsi2sd(xmm0, scratch2);
567 __ jmp(&do_store); 567 __ jmp(&do_store);
568 568
569 __ bind(&heap_number); 569 __ bind(&heap_number);
570 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label, 570 __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
571 DONT_DO_SMI_CHECK); 571 DONT_DO_SMI_CHECK);
572 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 572 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
573 __ bind(&do_store); 573 __ bind(&do_store);
574 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); 574 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0);
575 // Return the value (register rax). 575 // Return the value (register rax).
576 ASSERT(value_reg.is(rax)); 576 DCHECK(value_reg.is(rax));
577 __ ret(0); 577 __ ret(0);
578 return; 578 return;
579 } 579 }
580 580
581 // TODO(verwaest): Share this code as a code stub. 581 // TODO(verwaest): Share this code as a code stub.
582 SmiCheck smi_check = representation.IsTagged() 582 SmiCheck smi_check = representation.IsTagged()
583 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 583 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
584 if (index.is_inobject()) { 584 if (index.is_inobject()) {
585 // Set the property straight into the object. 585 // Set the property straight into the object.
586 __ movp(FieldOperand(receiver_reg, index.offset()), value_reg); 586 __ movp(FieldOperand(receiver_reg, index.offset()), value_reg);
(...skipping 16 matching lines...) Expand all
603 // Update the write barrier for the array address. 603 // Update the write barrier for the array address.
604 // Pass the value being stored in the now unused name_reg. 604 // Pass the value being stored in the now unused name_reg.
605 __ movp(name_reg, value_reg); 605 __ movp(name_reg, value_reg);
606 __ RecordWriteField( 606 __ RecordWriteField(
607 scratch1, index.offset(), name_reg, receiver_reg, kDontSaveFPRegs, 607 scratch1, index.offset(), name_reg, receiver_reg, kDontSaveFPRegs,
608 EMIT_REMEMBERED_SET, smi_check); 608 EMIT_REMEMBERED_SET, smi_check);
609 } 609 }
610 } 610 }
611 611
612 // Return the value (register rax). 612 // Return the value (register rax).
613 ASSERT(value_reg.is(rax)); 613 DCHECK(value_reg.is(rax));
614 __ ret(0); 614 __ ret(0);
615 } 615 }
616 616
617 617
618 Register PropertyHandlerCompiler::CheckPrototypes( 618 Register PropertyHandlerCompiler::CheckPrototypes(
619 Register object_reg, Register holder_reg, Register scratch1, 619 Register object_reg, Register holder_reg, Register scratch1,
620 Register scratch2, Handle<Name> name, Label* miss, 620 Register scratch2, Handle<Name> name, Label* miss,
621 PrototypeCheckType check) { 621 PrototypeCheckType check) {
622 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 622 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
623 623
624 // Make sure there's no overlap between holder and object registers. 624 // Make sure there's no overlap between holder and object registers.
625 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 625 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
626 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 626 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
627 && !scratch2.is(scratch1)); 627 && !scratch2.is(scratch1));
628 628
629 // Keep track of the current object in register reg. On the first 629 // Keep track of the current object in register reg. On the first
630 // iteration, reg is an alias for object_reg, on later iterations, 630 // iteration, reg is an alias for object_reg, on later iterations,
631 // it is an alias for holder_reg. 631 // it is an alias for holder_reg.
632 Register reg = object_reg; 632 Register reg = object_reg;
633 int depth = 0; 633 int depth = 0;
634 634
635 Handle<JSObject> current = Handle<JSObject>::null(); 635 Handle<JSObject> current = Handle<JSObject>::null();
636 if (type()->IsConstant()) { 636 if (type()->IsConstant()) {
637 current = Handle<JSObject>::cast(type()->AsConstant()->Value()); 637 current = Handle<JSObject>::cast(type()->AsConstant()->Value());
638 } 638 }
639 Handle<JSObject> prototype = Handle<JSObject>::null(); 639 Handle<JSObject> prototype = Handle<JSObject>::null();
640 Handle<Map> current_map = receiver_map; 640 Handle<Map> current_map = receiver_map;
641 Handle<Map> holder_map(holder()->map()); 641 Handle<Map> holder_map(holder()->map());
642 // Traverse the prototype chain and check the maps in the prototype chain for 642 // Traverse the prototype chain and check the maps in the prototype chain for
643 // fast and global objects or do negative lookup for normal objects. 643 // fast and global objects or do negative lookup for normal objects.
644 while (!current_map.is_identical_to(holder_map)) { 644 while (!current_map.is_identical_to(holder_map)) {
645 ++depth; 645 ++depth;
646 646
647 // Only global objects and objects that do not require access 647 // Only global objects and objects that do not require access
648 // checks are allowed in stubs. 648 // checks are allowed in stubs.
649 ASSERT(current_map->IsJSGlobalProxyMap() || 649 DCHECK(current_map->IsJSGlobalProxyMap() ||
650 !current_map->is_access_check_needed()); 650 !current_map->is_access_check_needed());
651 651
652 prototype = handle(JSObject::cast(current_map->prototype())); 652 prototype = handle(JSObject::cast(current_map->prototype()));
653 if (current_map->is_dictionary_map() && 653 if (current_map->is_dictionary_map() &&
654 !current_map->IsJSGlobalObjectMap() && 654 !current_map->IsJSGlobalObjectMap() &&
655 !current_map->IsJSGlobalProxyMap()) { 655 !current_map->IsJSGlobalProxyMap()) {
656 if (!name->IsUniqueName()) { 656 if (!name->IsUniqueName()) {
657 ASSERT(name->IsString()); 657 DCHECK(name->IsString());
658 name = factory()->InternalizeString(Handle<String>::cast(name)); 658 name = factory()->InternalizeString(Handle<String>::cast(name));
659 } 659 }
660 ASSERT(current.is_null() || 660 DCHECK(current.is_null() ||
661 current->property_dictionary()->FindEntry(name) == 661 current->property_dictionary()->FindEntry(name) ==
662 NameDictionary::kNotFound); 662 NameDictionary::kNotFound);
663 663
664 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, 664 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
665 scratch1, scratch2); 665 scratch1, scratch2);
666 666
667 __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 667 __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
668 reg = holder_reg; // From now on the object will be in holder_reg. 668 reg = holder_reg; // From now on the object will be in holder_reg.
669 __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 669 __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
670 } else { 670 } else {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 708
709 // Log the check depth. 709 // Log the check depth.
710 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 710 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
711 711
712 if (depth != 0 || check == CHECK_ALL_MAPS) { 712 if (depth != 0 || check == CHECK_ALL_MAPS) {
713 // Check the holder map. 713 // Check the holder map.
714 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); 714 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
715 } 715 }
716 716
717 // Perform security check for access to the global object. 717 // Perform security check for access to the global object.
718 ASSERT(current_map->IsJSGlobalProxyMap() || 718 DCHECK(current_map->IsJSGlobalProxyMap() ||
719 !current_map->is_access_check_needed()); 719 !current_map->is_access_check_needed());
720 if (current_map->IsJSGlobalProxyMap()) { 720 if (current_map->IsJSGlobalProxyMap()) {
721 __ CheckAccessGlobalProxy(reg, scratch1, miss); 721 __ CheckAccessGlobalProxy(reg, scratch1, miss);
722 } 722 }
723 723
724 // Return the register containing the holder. 724 // Return the register containing the holder.
725 return reg; 725 return reg;
726 } 726 }
727 727
728 728
(...skipping 20 matching lines...) Expand all
749 749
750 750
751 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg, 751 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
752 Handle<Name> name, 752 Handle<Name> name,
753 Handle<Object> callback) { 753 Handle<Object> callback) {
754 Label miss; 754 Label miss;
755 755
756 Register reg = FrontendHeader(object_reg, name, &miss); 756 Register reg = FrontendHeader(object_reg, name, &miss);
757 757
758 if (!holder()->HasFastProperties()) { 758 if (!holder()->HasFastProperties()) {
759 ASSERT(!holder()->IsGlobalObject()); 759 DCHECK(!holder()->IsGlobalObject());
760 ASSERT(!reg.is(scratch2())); 760 DCHECK(!reg.is(scratch2()));
761 ASSERT(!reg.is(scratch3())); 761 DCHECK(!reg.is(scratch3()));
762 ASSERT(!reg.is(scratch4())); 762 DCHECK(!reg.is(scratch4()));
763 763
764 // Load the properties dictionary. 764 // Load the properties dictionary.
765 Register dictionary = scratch4(); 765 Register dictionary = scratch4();
766 __ movp(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset)); 766 __ movp(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset));
767 767
768 // Probe the dictionary. 768 // Probe the dictionary.
769 Label probe_done; 769 Label probe_done;
770 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), 770 NameDictionaryLookupStub::GeneratePositiveLookup(masm(),
771 &miss, 771 &miss,
772 &probe_done, 772 &probe_done,
(...skipping 27 matching lines...) Expand all
800 Register reg, FieldIndex field, Representation representation) { 800 Register reg, FieldIndex field, Representation representation) {
801 if (!reg.is(receiver())) __ movp(receiver(), reg); 801 if (!reg.is(receiver())) __ movp(receiver(), reg);
802 LoadFieldStub stub(isolate(), field); 802 LoadFieldStub stub(isolate(), field);
803 GenerateTailCall(masm(), stub.GetCode()); 803 GenerateTailCall(masm(), stub.GetCode());
804 } 804 }
805 805
806 806
807 void NamedLoadHandlerCompiler::GenerateLoadCallback( 807 void NamedLoadHandlerCompiler::GenerateLoadCallback(
808 Register reg, Handle<ExecutableAccessorInfo> callback) { 808 Register reg, Handle<ExecutableAccessorInfo> callback) {
809 // Insert additional parameters into the stack frame above return address. 809 // Insert additional parameters into the stack frame above return address.
810 ASSERT(!scratch4().is(reg)); 810 DCHECK(!scratch4().is(reg));
811 __ PopReturnAddressTo(scratch4()); 811 __ PopReturnAddressTo(scratch4());
812 812
813 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 813 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
814 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 814 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
815 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 815 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
816 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 816 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
817 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 817 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
818 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 818 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
819 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 819 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
820 __ Push(receiver()); // receiver 820 __ Push(receiver()); // receiver
821 if (heap()->InNewSpace(callback->data())) { 821 if (heap()->InNewSpace(callback->data())) {
822 ASSERT(!scratch2().is(reg)); 822 DCHECK(!scratch2().is(reg));
823 __ Move(scratch2(), callback); 823 __ Move(scratch2(), callback);
824 __ Push(FieldOperand(scratch2(), 824 __ Push(FieldOperand(scratch2(),
825 ExecutableAccessorInfo::kDataOffset)); // data 825 ExecutableAccessorInfo::kDataOffset)); // data
826 } else { 826 } else {
827 __ Push(Handle<Object>(callback->data(), isolate())); 827 __ Push(Handle<Object>(callback->data(), isolate()));
828 } 828 }
829 ASSERT(!kScratchRegister.is(reg)); 829 DCHECK(!kScratchRegister.is(reg));
830 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 830 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
831 __ Push(kScratchRegister); // return value 831 __ Push(kScratchRegister); // return value
832 __ Push(kScratchRegister); // return value default 832 __ Push(kScratchRegister); // return value default
833 __ PushAddress(ExternalReference::isolate_address(isolate())); 833 __ PushAddress(ExternalReference::isolate_address(isolate()));
834 __ Push(reg); // holder 834 __ Push(reg); // holder
835 __ Push(name()); // name 835 __ Push(name()); // name
836 // Save a pointer to where we pushed the arguments pointer. This will be 836 // Save a pointer to where we pushed the arguments pointer. This will be
837 // passed as the const PropertyAccessorInfo& to the C++ callback. 837 // passed as the const PropertyAccessorInfo& to the C++ callback.
838 838
839 __ PushReturnAddressFrom(scratch4()); 839 __ PushReturnAddressFrom(scratch4());
(...skipping 11 matching lines...) Expand all
851 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 851 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
852 // Return the constant value. 852 // Return the constant value.
853 __ Move(rax, value); 853 __ Move(rax, value);
854 __ ret(0); 854 __ ret(0);
855 } 855 }
856 856
857 857
858 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg, 858 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg,
859 LookupResult* lookup, 859 LookupResult* lookup,
860 Handle<Name> name) { 860 Handle<Name> name) {
861 ASSERT(holder()->HasNamedInterceptor()); 861 DCHECK(holder()->HasNamedInterceptor());
862 ASSERT(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 862 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
863 863
864 // So far the most popular follow ups for interceptor loads are FIELD 864 // So far the most popular follow ups for interceptor loads are FIELD
865 // and CALLBACKS, so inline only them, other cases may be added 865 // and CALLBACKS, so inline only them, other cases may be added
866 // later. 866 // later.
867 bool compile_followup_inline = false; 867 bool compile_followup_inline = false;
868 if (lookup->IsFound() && lookup->IsCacheable()) { 868 if (lookup->IsFound() && lookup->IsCacheable()) {
869 if (lookup->IsField()) { 869 if (lookup->IsField()) {
870 compile_followup_inline = true; 870 compile_followup_inline = true;
871 } else if (lookup->type() == CALLBACKS && 871 } else if (lookup->type() == CALLBACKS &&
872 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 872 lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
873 Handle<ExecutableAccessorInfo> callback( 873 Handle<ExecutableAccessorInfo> callback(
874 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 874 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
875 compile_followup_inline = 875 compile_followup_inline =
876 callback->getter() != NULL && 876 callback->getter() != NULL &&
877 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback, 877 ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback,
878 type()); 878 type());
879 } 879 }
880 } 880 }
881 881
882 if (compile_followup_inline) { 882 if (compile_followup_inline) {
883 // Compile the interceptor call, followed by inline code to load the 883 // Compile the interceptor call, followed by inline code to load the
884 // property from further up the prototype chain if the call fails. 884 // property from further up the prototype chain if the call fails.
885 // Check that the maps haven't changed. 885 // Check that the maps haven't changed.
886 ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 886 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
887 887
888 // Preserve the receiver register explicitly whenever it is different from 888 // Preserve the receiver register explicitly whenever it is different from
889 // the holder and it is needed should the interceptor return without any 889 // the holder and it is needed should the interceptor return without any
890 // result. The CALLBACKS case needs the receiver to be passed into C++ code, 890 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
891 // the FIELD case might cause a miss during the prototype check. 891 // the FIELD case might cause a miss during the prototype check.
892 bool must_perfrom_prototype_check = *holder() != lookup->holder(); 892 bool must_perfrom_prototype_check = *holder() != lookup->holder();
893 bool must_preserve_receiver_reg = !receiver().is(holder_reg) && 893 bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
894 (lookup->type() == CALLBACKS || must_perfrom_prototype_check); 894 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
895 895
896 // Save necessary data before invoking an interceptor. 896 // Save necessary data before invoking an interceptor.
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 Register name = LoadIC::NameRegister(); 1075 Register name = LoadIC::NameRegister();
1076 static Register registers[] = { receiver, name, rax, rbx, rdi, r8 }; 1076 static Register registers[] = { receiver, name, rax, rbx, rdi, r8 };
1077 return registers; 1077 return registers;
1078 } 1078 }
1079 1079
1080 1080
1081 Register* PropertyAccessCompiler::store_calling_convention() { 1081 Register* PropertyAccessCompiler::store_calling_convention() {
1082 // receiver, name, scratch1, scratch2, scratch3. 1082 // receiver, name, scratch1, scratch2, scratch3.
1083 Register receiver = KeyedStoreIC::ReceiverRegister(); 1083 Register receiver = KeyedStoreIC::ReceiverRegister();
1084 Register name = KeyedStoreIC::NameRegister(); 1084 Register name = KeyedStoreIC::NameRegister();
1085 ASSERT(rbx.is(KeyedStoreIC::MapRegister())); 1085 DCHECK(rbx.is(KeyedStoreIC::MapRegister()));
1086 static Register registers[] = { receiver, name, rbx, rdi, r8 }; 1086 static Register registers[] = { receiver, name, rbx, rdi, r8 };
1087 return registers; 1087 return registers;
1088 } 1088 }
1089 1089
1090 1090
1091 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } 1091 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
1092 1092
1093 1093
1094 #undef __ 1094 #undef __
1095 #define __ ACCESS_MASM(masm) 1095 #define __ ACCESS_MASM(masm)
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 __ j(not_equal, &miss); 1183 __ j(not_equal, &miss);
1184 } 1184 }
1185 } 1185 }
1186 1186
1187 Label number_case; 1187 Label number_case;
1188 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 1188 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
1189 __ JumpIfSmi(receiver(), smi_target); 1189 __ JumpIfSmi(receiver(), smi_target);
1190 1190
1191 // Polymorphic keyed stores may use the map register 1191 // Polymorphic keyed stores may use the map register
1192 Register map_reg = scratch1(); 1192 Register map_reg = scratch1();
1193 ASSERT(kind() != Code::KEYED_STORE_IC || 1193 DCHECK(kind() != Code::KEYED_STORE_IC ||
1194 map_reg.is(KeyedStoreIC::MapRegister())); 1194 map_reg.is(KeyedStoreIC::MapRegister()));
1195 __ movp(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 1195 __ movp(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
1196 int receiver_count = types->length(); 1196 int receiver_count = types->length();
1197 int number_of_handled_maps = 0; 1197 int number_of_handled_maps = 0;
1198 for (int current = 0; current < receiver_count; ++current) { 1198 for (int current = 0; current < receiver_count; ++current) {
1199 Handle<HeapType> type = types->at(current); 1199 Handle<HeapType> type = types->at(current);
1200 Handle<Map> map = IC::TypeToMap(*type, isolate()); 1200 Handle<Map> map = IC::TypeToMap(*type, isolate());
1201 if (!map->is_deprecated()) { 1201 if (!map->is_deprecated()) {
1202 number_of_handled_maps++; 1202 number_of_handled_maps++;
1203 // Check map and tail call if there's a match 1203 // Check map and tail call if there's a match
1204 __ Cmp(map_reg, map); 1204 __ Cmp(map_reg, map);
1205 if (type->Is(HeapType::Number())) { 1205 if (type->Is(HeapType::Number())) {
1206 ASSERT(!number_case.is_unused()); 1206 DCHECK(!number_case.is_unused());
1207 __ bind(&number_case); 1207 __ bind(&number_case);
1208 } 1208 }
1209 __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET); 1209 __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET);
1210 } 1210 }
1211 } 1211 }
1212 ASSERT(number_of_handled_maps > 0); 1212 DCHECK(number_of_handled_maps > 0);
1213 1213
1214 __ bind(&miss); 1214 __ bind(&miss);
1215 TailCallBuiltin(masm(), MissBuiltin(kind())); 1215 TailCallBuiltin(masm(), MissBuiltin(kind()));
1216 1216
1217 // Return the generated code. 1217 // Return the generated code.
1218 InlineCacheState state = 1218 InlineCacheState state =
1219 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; 1219 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
1220 return GetCode(kind(), type, name, state); 1220 return GetCode(kind(), type, name, state);
1221 } 1221 }
1222 1222
1223 1223
1224 #undef __ 1224 #undef __
1225 #define __ ACCESS_MASM(masm) 1225 #define __ ACCESS_MASM(masm)
1226 1226
1227 1227
1228 void ElementHandlerCompiler::GenerateLoadDictionaryElement( 1228 void ElementHandlerCompiler::GenerateLoadDictionaryElement(
1229 MacroAssembler* masm) { 1229 MacroAssembler* masm) {
1230 // ----------- S t a t e ------------- 1230 // ----------- S t a t e -------------
1231 // -- rcx : key 1231 // -- rcx : key
1232 // -- rdx : receiver 1232 // -- rdx : receiver
1233 // -- rsp[0] : return address 1233 // -- rsp[0] : return address
1234 // ----------------------------------- 1234 // -----------------------------------
1235 ASSERT(rdx.is(LoadIC::ReceiverRegister())); 1235 DCHECK(rdx.is(LoadIC::ReceiverRegister()));
1236 ASSERT(rcx.is(LoadIC::NameRegister())); 1236 DCHECK(rcx.is(LoadIC::NameRegister()));
1237 Label slow, miss; 1237 Label slow, miss;
1238 1238
1239 // This stub is meant to be tail-jumped to, the receiver must already 1239 // This stub is meant to be tail-jumped to, the receiver must already
1240 // have been verified by the caller to not be a smi. 1240 // have been verified by the caller to not be a smi.
1241 1241
1242 __ JumpIfNotSmi(rcx, &miss); 1242 __ JumpIfNotSmi(rcx, &miss);
1243 __ SmiToInteger32(rbx, rcx); 1243 __ SmiToInteger32(rbx, rcx);
1244 __ movp(rax, FieldOperand(rdx, JSObject::kElementsOffset)); 1244 __ movp(rax, FieldOperand(rdx, JSObject::kElementsOffset));
1245 1245
1246 // Check whether the elements is a number dictionary. 1246 // Check whether the elements is a number dictionary.
(...skipping 20 matching lines...) Expand all
1267 // ----------------------------------- 1267 // -----------------------------------
1268 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1268 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1269 } 1269 }
1270 1270
1271 1271
1272 #undef __ 1272 #undef __
1273 1273
1274 } } // namespace v8::internal 1274 } } // namespace v8::internal
1275 1275
1276 #endif // V8_TARGET_ARCH_X64 1276 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/regexp-macro-assembler-x64.cc ('k') | src/x87/assembler-x87.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698