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

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

Issue 430783002: Cleanup in stub-cache.cc; remove unused ArrayLength store ICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Port 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/arm/stub-cache-arm.cc ('k') | src/ia32/stub-cache-ia32.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic-inl.h" 10 #include "src/ic-inl.h"
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 240 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
241 Register scratch, Label* miss) { 241 Register scratch, Label* miss) {
242 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 242 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
243 ASSERT(cell->value()->IsTheHole()); 243 ASSERT(cell->value()->IsTheHole());
244 __ Mov(scratch, Operand(cell)); 244 __ Mov(scratch, Operand(cell));
245 __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 245 __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
246 __ JumpIfNotRoot(scratch, Heap::kTheHoleValueRootIndex, miss); 246 __ JumpIfNotRoot(scratch, Heap::kTheHoleValueRootIndex, miss);
247 } 247 }
248 248
249 249
250 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
251 Register holder, Register name,
252 Handle<JSObject> holder_obj) {
253 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
254 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
255 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
256 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
257 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
258
259 __ Push(name);
260 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
261 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
262 Register scratch = name;
263 __ Mov(scratch, Operand(interceptor));
264 __ Push(scratch, receiver, holder);
265 }
266
267
268 static void CompileCallLoadPropertyWithInterceptor(
269 MacroAssembler* masm, Register receiver, Register holder, Register name,
270 Handle<JSObject> holder_obj, IC::UtilityId id) {
271 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
272
273 __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
274 NamedLoadHandlerCompiler::kInterceptorArgsLength);
275 }
276
277
278 // Generate call to api function.
279 void PropertyHandlerCompiler::GenerateFastApiCall(
280 MacroAssembler* masm, const CallOptimization& optimization,
281 Handle<Map> receiver_map, Register receiver, Register scratch,
282 bool is_store, int argc, Register* values) {
283 ASSERT(!AreAliased(receiver, scratch));
284
285 MacroAssembler::PushPopQueue queue(masm);
286 queue.Queue(receiver);
287 // Write the arguments to the stack frame.
288 for (int i = 0; i < argc; i++) {
289 Register arg = values[argc - 1 - i];
290 ASSERT(!AreAliased(receiver, scratch, arg));
291 queue.Queue(arg);
292 }
293 queue.PushQueued();
294
295 ASSERT(optimization.is_simple_api_call());
296
297 // Abi for CallApiFunctionStub.
298 Register callee = x0;
299 Register call_data = x4;
300 Register holder = x2;
301 Register api_function_address = x1;
302
303 // Put holder in place.
304 CallOptimization::HolderLookup holder_lookup;
305 Handle<JSObject> api_holder =
306 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
307 switch (holder_lookup) {
308 case CallOptimization::kHolderIsReceiver:
309 __ Mov(holder, receiver);
310 break;
311 case CallOptimization::kHolderFound:
312 __ LoadObject(holder, api_holder);
313 break;
314 case CallOptimization::kHolderNotFound:
315 UNREACHABLE();
316 break;
317 }
318
319 Isolate* isolate = masm->isolate();
320 Handle<JSFunction> function = optimization.constant_function();
321 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
322 Handle<Object> call_data_obj(api_call_info->data(), isolate);
323
324 // Put callee in place.
325 __ LoadObject(callee, function);
326
327 bool call_data_undefined = false;
328 // Put call_data in place.
329 if (isolate->heap()->InNewSpace(*call_data_obj)) {
330 __ LoadObject(call_data, api_call_info);
331 __ Ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
332 } else if (call_data_obj->IsUndefined()) {
333 call_data_undefined = true;
334 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
335 } else {
336 __ LoadObject(call_data, call_data_obj);
337 }
338
339 // Put api_function_address in place.
340 Address function_address = v8::ToCData<Address>(api_call_info->callback());
341 ApiFunction fun(function_address);
342 ExternalReference ref = ExternalReference(
343 &fun, ExternalReference::DIRECT_API_CALL, masm->isolate());
344 __ Mov(api_function_address, ref);
345
346 // Jump to stub.
347 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
348 __ TailCallStub(&stub);
349 }
350
351
352 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
353 Handle<Code> code) {
354 __ Jump(code, RelocInfo::CODE_TARGET);
355 }
356
357
358 #undef __
359 #define __ ACCESS_MASM(masm())
360
361
362 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
363 Handle<Name> name) {
364 if (!label->is_unused()) {
365 __ Bind(label);
366 __ Mov(this->name(), Operand(name));
367 }
368 }
369
370
250 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup( 371 void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
251 MacroAssembler* masm, Handle<JSObject> holder, Register holder_reg, 372 Register holder_reg, Handle<Name> name, Label* miss) {
252 Handle<Name> name, Label* miss) { 373 if (holder()->IsJSGlobalObject()) {
253 if (holder->IsJSGlobalObject()) { 374 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(holder()),
254 GenerateCheckPropertyCell( 375 name, scratch1(), miss);
255 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); 376 } else if (!holder()->HasFastProperties()) {
256 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 377 GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1(),
257 GenerateDictionaryNegativeLookup( 378 scratch2());
258 masm, miss, holder_reg, name, scratch1(), scratch2());
259 } 379 }
260 } 380 }
261 381
262 382
263 // Generate StoreTransition code, value is passed in x0 register. 383 // Generate StoreTransition code, value is passed in x0 register.
264 // When leaving generated code after success, the receiver_reg and storage_reg 384 // When leaving generated code after success, the receiver_reg and storage_reg
265 // may be clobbered. Upon branch to miss_label, the receiver and name registers 385 // may be clobbered. Upon branch to miss_label, the receiver and name registers
266 // have their original values. 386 // have their original values.
267 void NamedStoreHandlerCompiler::GenerateStoreTransition( 387 void NamedStoreHandlerCompiler::GenerateStoreTransition(
268 MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition, 388 Handle<Map> transition, Handle<Name> name, Register receiver_reg,
269 Handle<Name> name, Register receiver_reg, Register storage_reg, 389 Register storage_reg, Register value_reg, Register scratch1,
270 Register value_reg, Register scratch1, Register scratch2, Register scratch3, 390 Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
271 Label* miss_label, Label* slow) {
272 Label exit; 391 Label exit;
273 392
274 ASSERT(!AreAliased(receiver_reg, storage_reg, value_reg, 393 ASSERT(!AreAliased(receiver_reg, storage_reg, value_reg,
275 scratch1, scratch2, scratch3)); 394 scratch1, scratch2, scratch3));
276 395
277 // We don't need scratch3. 396 // We don't need scratch3.
278 scratch3 = NoReg; 397 scratch3 = NoReg;
279 398
280 int descriptor = transition->LastAdded(); 399 int descriptor = transition->LastAdded();
281 DescriptorArray* descriptors = transition->instance_descriptors(); 400 DescriptorArray* descriptors = transition->instance_descriptors();
282 PropertyDetails details = descriptors->GetDetails(descriptor); 401 PropertyDetails details = descriptors->GetDetails(descriptor);
283 Representation representation = details.representation(); 402 Representation representation = details.representation();
284 ASSERT(!representation.IsNone()); 403 ASSERT(!representation.IsNone());
285 404
286 if (details.type() == CONSTANT) { 405 if (details.type() == CONSTANT) {
287 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 406 Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
288 __ LoadObject(scratch1, constant); 407 __ LoadObject(scratch1, constant);
289 __ Cmp(value_reg, scratch1); 408 __ Cmp(value_reg, scratch1);
290 __ B(ne, miss_label); 409 __ B(ne, miss_label);
291 } else if (representation.IsSmi()) { 410 } else if (representation.IsSmi()) {
292 __ JumpIfNotSmi(value_reg, miss_label); 411 __ JumpIfNotSmi(value_reg, miss_label);
293 } else if (representation.IsHeapObject()) { 412 } else if (representation.IsHeapObject()) {
294 __ JumpIfSmi(value_reg, miss_label); 413 __ JumpIfSmi(value_reg, miss_label);
295 HeapType* field_type = descriptors->GetFieldType(descriptor); 414 HeapType* field_type = descriptors->GetFieldType(descriptor);
296 HeapType::Iterator<Map> it = field_type->Classes(); 415 HeapType::Iterator<Map> it = field_type->Classes();
297 if (!it.Done()) { 416 if (!it.Done()) {
298 __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 417 __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
299 Label do_store; 418 Label do_store;
300 while (true) { 419 while (true) {
301 __ CompareMap(scratch1, it.Current()); 420 __ CompareMap(scratch1, it.Current());
302 it.Advance(); 421 it.Advance();
303 if (it.Done()) { 422 if (it.Done()) {
304 __ B(ne, miss_label); 423 __ B(ne, miss_label);
305 break; 424 break;
306 } 425 }
307 __ B(eq, &do_store); 426 __ B(eq, &do_store);
308 } 427 }
309 __ Bind(&do_store); 428 __ Bind(&do_store);
310 } 429 }
311 } else if (representation.IsDouble()) { 430 } else if (representation.IsDouble()) {
312 UseScratchRegisterScope temps(masm); 431 UseScratchRegisterScope temps(masm());
313 DoubleRegister temp_double = temps.AcquireD(); 432 DoubleRegister temp_double = temps.AcquireD();
314 __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag); 433 __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag);
315 434
316 Label do_store; 435 Label do_store;
317 __ JumpIfSmi(value_reg, &do_store); 436 __ JumpIfSmi(value_reg, &do_store);
318 437
319 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, 438 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
320 miss_label, DONT_DO_SMI_CHECK); 439 miss_label, DONT_DO_SMI_CHECK);
321 __ Ldr(temp_double, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 440 __ Ldr(temp_double, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
322 441
323 __ Bind(&do_store); 442 __ Bind(&do_store);
324 __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2, temp_double, 443 __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2, temp_double,
325 NoReg, MUTABLE); 444 NoReg, MUTABLE);
326 } 445 }
327 446
328 // Stub never generated for objects that require access checks. 447 // Stub never generated for objects that require access checks.
329 ASSERT(!transition->is_access_check_needed()); 448 ASSERT(!transition->is_access_check_needed());
330 449
331 // Perform map transition for the receiver if necessary. 450 // Perform map transition for the receiver if necessary.
332 if (details.type() == FIELD && 451 if (details.type() == FIELD &&
333 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) { 452 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
334 // The properties must be extended before we can store the value. 453 // The properties must be extended before we can store the value.
335 // We jump to a runtime call that extends the properties array. 454 // We jump to a runtime call that extends the properties array.
336 __ Mov(scratch1, Operand(transition)); 455 __ Mov(scratch1, Operand(transition));
337 __ Push(receiver_reg, scratch1, value_reg); 456 __ Push(receiver_reg, scratch1, value_reg);
338 __ TailCallExternalReference( 457 __ TailCallExternalReference(
339 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 458 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
340 masm->isolate()), 459 isolate()),
341 3, 460 3, 1);
342 1);
343 return; 461 return;
344 } 462 }
345 463
346 // Update the map of the object. 464 // Update the map of the object.
347 __ Mov(scratch1, Operand(transition)); 465 __ Mov(scratch1, Operand(transition));
348 __ Str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 466 __ Str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
349 467
350 // Update the write barrier for the map field. 468 // Update the write barrier for the map field.
351 __ RecordWriteField(receiver_reg, 469 __ RecordWriteField(receiver_reg,
352 HeapObject::kMapOffset, 470 HeapObject::kMapOffset,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 ASSERT(value_reg.is(x0)); 541 ASSERT(value_reg.is(x0));
424 __ Ret(); 542 __ Ret();
425 } 543 }
426 544
427 545
428 // Generate StoreField code, value is passed in x0 register. 546 // Generate StoreField code, value is passed in x0 register.
429 // When leaving generated code after success, the receiver_reg and name_reg may 547 // When leaving generated code after success, the receiver_reg and name_reg may
430 // be clobbered. Upon branch to miss_label, the receiver and name registers have 548 // be clobbered. Upon branch to miss_label, the receiver and name registers have
431 // their original values. 549 // their original values.
432 void NamedStoreHandlerCompiler::GenerateStoreField( 550 void NamedStoreHandlerCompiler::GenerateStoreField(
433 MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup, 551 Handle<JSObject> object, LookupResult* lookup, Register receiver_reg,
434 Register receiver_reg, Register name_reg, Register value_reg, 552 Register name_reg, Register value_reg, Register scratch1, Register scratch2,
435 Register scratch1, Register scratch2, Label* miss_label) { 553 Label* miss_label) {
436 // x0 : value 554 // x0 : value
437 Label exit; 555 Label exit;
438 556
439 // Stub never generated for non-global objects that require access 557 // Stub never generated for objects that require access checks.
440 // checks. 558 ASSERT(!object->IsAccessCheckNeeded());
441 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 559 ASSERT(!object->IsJSGlobalProxy());
442 560
443 FieldIndex index = lookup->GetFieldIndex(); 561 FieldIndex index = lookup->GetFieldIndex();
444 562
445 Representation representation = lookup->representation(); 563 Representation representation = lookup->representation();
446 ASSERT(!representation.IsNone()); 564 ASSERT(!representation.IsNone());
447 if (representation.IsSmi()) { 565 if (representation.IsSmi()) {
448 __ JumpIfNotSmi(value_reg, miss_label); 566 __ JumpIfNotSmi(value_reg, miss_label);
449 } else if (representation.IsHeapObject()) { 567 } else if (representation.IsHeapObject()) {
450 __ JumpIfSmi(value_reg, miss_label); 568 __ JumpIfSmi(value_reg, miss_label);
451 HeapType* field_type = lookup->GetFieldType(); 569 HeapType* field_type = lookup->GetFieldType();
452 HeapType::Iterator<Map> it = field_type->Classes(); 570 HeapType::Iterator<Map> it = field_type->Classes();
453 if (!it.Done()) { 571 if (!it.Done()) {
454 __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 572 __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
455 Label do_store; 573 Label do_store;
456 while (true) { 574 while (true) {
457 __ CompareMap(scratch1, it.Current()); 575 __ CompareMap(scratch1, it.Current());
458 it.Advance(); 576 it.Advance();
459 if (it.Done()) { 577 if (it.Done()) {
460 __ B(ne, miss_label); 578 __ B(ne, miss_label);
461 break; 579 break;
462 } 580 }
463 __ B(eq, &do_store); 581 __ B(eq, &do_store);
464 } 582 }
465 __ Bind(&do_store); 583 __ Bind(&do_store);
466 } 584 }
467 } else if (representation.IsDouble()) { 585 } else if (representation.IsDouble()) {
468 UseScratchRegisterScope temps(masm); 586 UseScratchRegisterScope temps(masm());
469 DoubleRegister temp_double = temps.AcquireD(); 587 DoubleRegister temp_double = temps.AcquireD();
470 588
471 __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag); 589 __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag);
472 590
473 // Load the double storage. 591 // Load the double storage.
474 if (index.is_inobject()) { 592 if (index.is_inobject()) {
475 __ Ldr(scratch1, FieldMemOperand(receiver_reg, index.offset())); 593 __ Ldr(scratch1, FieldMemOperand(receiver_reg, index.offset()));
476 } else { 594 } else {
477 __ Ldr(scratch1, 595 __ Ldr(scratch1,
478 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 596 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 } 663 }
546 } 664 }
547 665
548 __ Bind(&exit); 666 __ Bind(&exit);
549 // Return the value (register x0). 667 // Return the value (register x0).
550 ASSERT(value_reg.is(x0)); 668 ASSERT(value_reg.is(x0));
551 __ Ret(); 669 __ Ret();
552 } 670 }
553 671
554 672
555 void NamedStoreHandlerCompiler::GenerateRestoreName(MacroAssembler* masm,
556 Label* label,
557 Handle<Name> name) {
558 if (!label->is_unused()) {
559 __ Bind(label);
560 __ Mov(this->name(), Operand(name));
561 }
562 }
563
564
565 static void PushInterceptorArguments(MacroAssembler* masm,
566 Register receiver,
567 Register holder,
568 Register name,
569 Handle<JSObject> holder_obj) {
570 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
571 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
572 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
573 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
574 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
575
576 __ Push(name);
577 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
578 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
579 Register scratch = name;
580 __ Mov(scratch, Operand(interceptor));
581 __ Push(scratch, receiver, holder);
582 }
583
584
585 static void CompileCallLoadPropertyWithInterceptor(
586 MacroAssembler* masm,
587 Register receiver,
588 Register holder,
589 Register name,
590 Handle<JSObject> holder_obj,
591 IC::UtilityId id) {
592 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
593
594 __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
595 NamedLoadHandlerCompiler::kInterceptorArgsLength);
596 }
597
598
599 // Generate call to api function.
600 void PropertyHandlerCompiler::GenerateFastApiCall(
601 MacroAssembler* masm, const CallOptimization& optimization,
602 Handle<Map> receiver_map, Register receiver, Register scratch,
603 bool is_store, int argc, Register* values) {
604 ASSERT(!AreAliased(receiver, scratch));
605
606 MacroAssembler::PushPopQueue queue(masm);
607 queue.Queue(receiver);
608 // Write the arguments to the stack frame.
609 for (int i = 0; i < argc; i++) {
610 Register arg = values[argc-1-i];
611 ASSERT(!AreAliased(receiver, scratch, arg));
612 queue.Queue(arg);
613 }
614 queue.PushQueued();
615
616 ASSERT(optimization.is_simple_api_call());
617
618 // Abi for CallApiFunctionStub.
619 Register callee = x0;
620 Register call_data = x4;
621 Register holder = x2;
622 Register api_function_address = x1;
623
624 // Put holder in place.
625 CallOptimization::HolderLookup holder_lookup;
626 Handle<JSObject> api_holder =
627 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
628 switch (holder_lookup) {
629 case CallOptimization::kHolderIsReceiver:
630 __ Mov(holder, receiver);
631 break;
632 case CallOptimization::kHolderFound:
633 __ LoadObject(holder, api_holder);
634 break;
635 case CallOptimization::kHolderNotFound:
636 UNREACHABLE();
637 break;
638 }
639
640 Isolate* isolate = masm->isolate();
641 Handle<JSFunction> function = optimization.constant_function();
642 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
643 Handle<Object> call_data_obj(api_call_info->data(), isolate);
644
645 // Put callee in place.
646 __ LoadObject(callee, function);
647
648 bool call_data_undefined = false;
649 // Put call_data in place.
650 if (isolate->heap()->InNewSpace(*call_data_obj)) {
651 __ LoadObject(call_data, api_call_info);
652 __ Ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
653 } else if (call_data_obj->IsUndefined()) {
654 call_data_undefined = true;
655 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
656 } else {
657 __ LoadObject(call_data, call_data_obj);
658 }
659
660 // Put api_function_address in place.
661 Address function_address = v8::ToCData<Address>(api_call_info->callback());
662 ApiFunction fun(function_address);
663 ExternalReference ref = ExternalReference(&fun,
664 ExternalReference::DIRECT_API_CALL,
665 masm->isolate());
666 __ Mov(api_function_address, ref);
667
668 // Jump to stub.
669 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
670 __ TailCallStub(&stub);
671 }
672
673
674 void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
675 Handle<Code> code) {
676 __ Jump(code, RelocInfo::CODE_TARGET);
677 }
678
679
680 #undef __
681 #define __ ACCESS_MASM(masm())
682
683
684 Register PropertyHandlerCompiler::CheckPrototypes( 673 Register PropertyHandlerCompiler::CheckPrototypes(
685 Register object_reg, Register holder_reg, Register scratch1, 674 Register object_reg, Register holder_reg, Register scratch1,
686 Register scratch2, Handle<Name> name, Label* miss, 675 Register scratch2, Handle<Name> name, Label* miss,
687 PrototypeCheckType check) { 676 PrototypeCheckType check) {
688 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate())); 677 Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
689 678
690 // object_reg and holder_reg registers can alias. 679 // object_reg and holder_reg registers can alias.
691 ASSERT(!AreAliased(object_reg, scratch1, scratch2)); 680 ASSERT(!AreAliased(object_reg, scratch1, scratch2));
692 ASSERT(!AreAliased(holder_reg, scratch1, scratch2)); 681 ASSERT(!AreAliased(holder_reg, scratch1, scratch2));
693 682
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 __ Bind(&success); 791 __ Bind(&success);
803 } 792 }
804 } 793 }
805 794
806 795
807 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 796 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
808 if (!miss->is_unused()) { 797 if (!miss->is_unused()) {
809 Label success; 798 Label success;
810 __ B(&success); 799 __ B(&success);
811 800
812 GenerateRestoreName(masm(), miss, name); 801 GenerateRestoreName(miss, name);
813 TailCallBuiltin(masm(), MissBuiltin(kind())); 802 TailCallBuiltin(masm(), MissBuiltin(kind()));
814 803
815 __ Bind(&success); 804 __ Bind(&success);
816 } 805 }
817 } 806 }
818 807
819 808
820 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg, 809 Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
821 Handle<Name> name, 810 Handle<Name> name,
822 Handle<Object> callback) { 811 Handle<Object> callback) {
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 __ Bind(&miss); 1268 __ Bind(&miss);
1280 TailCallBuiltin(masm(), MissBuiltin(kind())); 1269 TailCallBuiltin(masm(), MissBuiltin(kind()));
1281 1270
1282 // Return the generated code. 1271 // Return the generated code.
1283 InlineCacheState state = 1272 InlineCacheState state =
1284 (number_of_handled_maps > 1) ? POLYMORPHIC : MONOMORPHIC; 1273 (number_of_handled_maps > 1) ? POLYMORPHIC : MONOMORPHIC;
1285 return GetCode(kind(), type, name, state); 1274 return GetCode(kind(), type, name, state);
1286 } 1275 }
1287 1276
1288 1277
1289 void NamedStoreHandlerCompiler::GenerateStoreArrayLength() {
1290 // Prepare tail call to StoreIC_ArrayLength.
1291 __ Push(receiver(), value());
1292
1293 ExternalReference ref =
1294 ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength),
1295 masm()->isolate());
1296 __ TailCallExternalReference(ref, 2, 1);
1297 }
1298
1299
1300 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( 1278 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
1301 MapHandleList* receiver_maps, CodeHandleList* handler_stubs, 1279 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
1302 MapHandleList* transitioned_maps) { 1280 MapHandleList* transitioned_maps) {
1303 Label miss; 1281 Label miss;
1304 1282
1305 ASM_LOCATION("PropertyICCompiler::CompileStorePolymorphic"); 1283 ASM_LOCATION("PropertyICCompiler::CompileStorePolymorphic");
1306 1284
1307 __ JumpIfSmi(receiver(), &miss); 1285 __ JumpIfSmi(receiver(), &miss);
1308 1286
1309 int receiver_count = receiver_maps->length(); 1287 int receiver_count = receiver_maps->length();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 1333
1356 // Miss case, call the runtime. 1334 // Miss case, call the runtime.
1357 __ Bind(&miss); 1335 __ Bind(&miss);
1358 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1336 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1359 } 1337 }
1360 1338
1361 1339
1362 } } // namespace v8::internal 1340 } } // namespace v8::internal
1363 1341
1364 #endif // V8_TARGET_ARCH_ARM64 1342 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698