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

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

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 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/macro-assembler-arm.cc ('k') | src/array.js » ('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 // 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 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 315 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
316 } 316 }
317 317
318 318
319 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 319 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
320 Register dst, 320 Register dst,
321 Register src, 321 Register src,
322 bool inobject, 322 bool inobject,
323 int index, 323 int index,
324 Representation representation) { 324 Representation representation) {
325 ASSERT(!FLAG_track_double_fields || !representation.IsDouble()); 325 ASSERT(!representation.IsDouble());
326 int offset = index * kPointerSize; 326 int offset = index * kPointerSize;
327 if (!inobject) { 327 if (!inobject) {
328 // Calculate the offset into the properties array. 328 // Calculate the offset into the properties array.
329 offset = offset + FixedArray::kHeaderSize; 329 offset = offset + FixedArray::kHeaderSize;
330 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); 330 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
331 src = dst; 331 src = dst;
332 } 332 }
333 __ ldr(dst, FieldMemOperand(src, offset)); 333 __ ldr(dst, FieldMemOperand(src, offset));
334 } 334 }
335 335
336 336
337 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 337 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
338 Register receiver, 338 Register receiver,
339 Register scratch, 339 Register scratch,
340 Label* miss_label) { 340 Label* miss_label) {
341 // Check that the receiver isn't a smi. 341 // Check that the receiver isn't a smi.
342 __ JumpIfSmi(receiver, miss_label); 342 __ JumpIfSmi(receiver, miss_label);
343 343
344 // Check that the object is a JS array. 344 // Check that the object is a JS array.
345 __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE); 345 __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE);
346 __ b(ne, miss_label); 346 __ b(ne, miss_label);
347 347
348 // Load length directly from the JS array. 348 // Load length directly from the JS array.
349 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 349 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
350 __ Ret(); 350 __ Ret();
351 } 351 }
352 352
353 353
354 // Generate code to check if an object is a string. If the object is a
355 // heap object, its map's instance type is left in the scratch1 register.
356 // If this is not needed, scratch1 and scratch2 may be the same register.
357 static void GenerateStringCheck(MacroAssembler* masm,
358 Register receiver,
359 Register scratch1,
360 Register scratch2,
361 Label* smi,
362 Label* non_string_object) {
363 // Check that the receiver isn't a smi.
364 __ JumpIfSmi(receiver, smi);
365
366 // Check that the object is a string.
367 __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset));
368 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
369 __ and_(scratch2, scratch1, Operand(kIsNotStringMask));
370 // The cast is to resolve the overload for the argument of 0x0.
371 __ cmp(scratch2, Operand(static_cast<int32_t>(kStringTag)));
372 __ b(ne, non_string_object);
373 }
374
375
376 // Generate code to load the length from a string object and return the length.
377 // If the receiver object is not a string or a wrapped string object the
378 // execution continues at the miss label. The register containing the
379 // receiver is potentially clobbered.
380 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
381 Register receiver,
382 Register scratch1,
383 Register scratch2,
384 Label* miss) {
385 Label check_wrapper;
386
387 // Check if the object is a string leaving the instance type in the
388 // scratch1 register.
389 GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, &check_wrapper);
390
391 // Load length directly from the string.
392 __ ldr(r0, FieldMemOperand(receiver, String::kLengthOffset));
393 __ Ret();
394
395 // Check if the object is a JSValue wrapper.
396 __ bind(&check_wrapper);
397 __ cmp(scratch1, Operand(JS_VALUE_TYPE));
398 __ b(ne, miss);
399
400 // Unwrap the value and check if the wrapped value is a string.
401 __ ldr(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset));
402 GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss);
403 __ ldr(r0, FieldMemOperand(scratch1, String::kLengthOffset));
404 __ Ret();
405 }
406
407
408 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, 354 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
409 Register receiver, 355 Register receiver,
410 Register scratch1, 356 Register scratch1,
411 Register scratch2, 357 Register scratch2,
412 Label* miss_label) { 358 Label* miss_label) {
413 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 359 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
414 __ mov(r0, scratch1); 360 __ mov(r0, scratch1);
415 __ Ret(); 361 __ Ret();
416 } 362 }
417 363
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 DescriptorArray* descriptors = transition->instance_descriptors(); 420 DescriptorArray* descriptors = transition->instance_descriptors();
475 PropertyDetails details = descriptors->GetDetails(descriptor); 421 PropertyDetails details = descriptors->GetDetails(descriptor);
476 Representation representation = details.representation(); 422 Representation representation = details.representation();
477 ASSERT(!representation.IsNone()); 423 ASSERT(!representation.IsNone());
478 424
479 if (details.type() == CONSTANT) { 425 if (details.type() == CONSTANT) {
480 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 426 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate());
481 __ Move(scratch1, constant); 427 __ Move(scratch1, constant);
482 __ cmp(value_reg, scratch1); 428 __ cmp(value_reg, scratch1);
483 __ b(ne, miss_label); 429 __ b(ne, miss_label);
484 } else if (FLAG_track_fields && representation.IsSmi()) { 430 } else if (representation.IsSmi()) {
485 __ JumpIfNotSmi(value_reg, miss_label); 431 __ JumpIfNotSmi(value_reg, miss_label);
486 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 432 } else if (representation.IsHeapObject()) {
487 __ JumpIfSmi(value_reg, miss_label); 433 __ JumpIfSmi(value_reg, miss_label);
488 } else if (FLAG_track_double_fields && representation.IsDouble()) { 434 } else if (representation.IsDouble()) {
489 Label do_store, heap_number; 435 Label do_store, heap_number;
490 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); 436 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex);
491 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow); 437 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow);
492 438
493 __ JumpIfNotSmi(value_reg, &heap_number); 439 __ JumpIfNotSmi(value_reg, &heap_number);
494 __ SmiUntag(scratch1, value_reg); 440 __ SmiUntag(scratch1, value_reg);
495 __ vmov(s0, scratch1); 441 __ vmov(s0, scratch1);
496 __ vcvt_f64_s32(d0, s0); 442 __ vcvt_f64_s32(d0, s0);
497 __ jmp(&do_store); 443 __ jmp(&do_store);
498 444
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 // face of a transition we can use the old map here because the size of the 498 // face of a transition we can use the old map here because the size of the
553 // object and the number of in-object properties is not going to change. 499 // object and the number of in-object properties is not going to change.
554 index -= object->map()->inobject_properties(); 500 index -= object->map()->inobject_properties();
555 501
556 // TODO(verwaest): Share this code as a code stub. 502 // TODO(verwaest): Share this code as a code stub.
557 SmiCheck smi_check = representation.IsTagged() 503 SmiCheck smi_check = representation.IsTagged()
558 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 504 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
559 if (index < 0) { 505 if (index < 0) {
560 // Set the property straight into the object. 506 // Set the property straight into the object.
561 int offset = object->map()->instance_size() + (index * kPointerSize); 507 int offset = object->map()->instance_size() + (index * kPointerSize);
562 if (FLAG_track_double_fields && representation.IsDouble()) { 508 if (representation.IsDouble()) {
563 __ str(storage_reg, FieldMemOperand(receiver_reg, offset)); 509 __ str(storage_reg, FieldMemOperand(receiver_reg, offset));
564 } else { 510 } else {
565 __ str(value_reg, FieldMemOperand(receiver_reg, offset)); 511 __ str(value_reg, FieldMemOperand(receiver_reg, offset));
566 } 512 }
567 513
568 if (!FLAG_track_fields || !representation.IsSmi()) { 514 if (!representation.IsSmi()) {
569 // Update the write barrier for the array address. 515 // Update the write barrier for the array address.
570 if (!FLAG_track_double_fields || !representation.IsDouble()) { 516 if (!representation.IsDouble()) {
571 __ mov(storage_reg, value_reg); 517 __ mov(storage_reg, value_reg);
572 } 518 }
573 __ RecordWriteField(receiver_reg, 519 __ RecordWriteField(receiver_reg,
574 offset, 520 offset,
575 storage_reg, 521 storage_reg,
576 scratch1, 522 scratch1,
577 kLRHasNotBeenSaved, 523 kLRHasNotBeenSaved,
578 kDontSaveFPRegs, 524 kDontSaveFPRegs,
579 EMIT_REMEMBERED_SET, 525 EMIT_REMEMBERED_SET,
580 smi_check); 526 smi_check);
581 } 527 }
582 } else { 528 } else {
583 // Write to the properties array. 529 // Write to the properties array.
584 int offset = index * kPointerSize + FixedArray::kHeaderSize; 530 int offset = index * kPointerSize + FixedArray::kHeaderSize;
585 // Get the properties array 531 // Get the properties array
586 __ ldr(scratch1, 532 __ ldr(scratch1,
587 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 533 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
588 if (FLAG_track_double_fields && representation.IsDouble()) { 534 if (representation.IsDouble()) {
589 __ str(storage_reg, FieldMemOperand(scratch1, offset)); 535 __ str(storage_reg, FieldMemOperand(scratch1, offset));
590 } else { 536 } else {
591 __ str(value_reg, FieldMemOperand(scratch1, offset)); 537 __ str(value_reg, FieldMemOperand(scratch1, offset));
592 } 538 }
593 539
594 if (!FLAG_track_fields || !representation.IsSmi()) { 540 if (!representation.IsSmi()) {
595 // Update the write barrier for the array address. 541 // Update the write barrier for the array address.
596 if (!FLAG_track_double_fields || !representation.IsDouble()) { 542 if (!representation.IsDouble()) {
597 __ mov(storage_reg, value_reg); 543 __ mov(storage_reg, value_reg);
598 } 544 }
599 __ RecordWriteField(scratch1, 545 __ RecordWriteField(scratch1,
600 offset, 546 offset,
601 storage_reg, 547 storage_reg,
602 receiver_reg, 548 receiver_reg,
603 kLRHasNotBeenSaved, 549 kLRHasNotBeenSaved,
604 kDontSaveFPRegs, 550 kDontSaveFPRegs,
605 EMIT_REMEMBERED_SET, 551 EMIT_REMEMBERED_SET,
606 smi_check); 552 smi_check);
(...skipping 29 matching lines...) Expand all
636 582
637 int index = lookup->GetFieldIndex().field_index(); 583 int index = lookup->GetFieldIndex().field_index();
638 584
639 // Adjust for the number of properties stored in the object. Even in the 585 // Adjust for the number of properties stored in the object. Even in the
640 // face of a transition we can use the old map here because the size of the 586 // face of a transition we can use the old map here because the size of the
641 // object and the number of in-object properties is not going to change. 587 // object and the number of in-object properties is not going to change.
642 index -= object->map()->inobject_properties(); 588 index -= object->map()->inobject_properties();
643 589
644 Representation representation = lookup->representation(); 590 Representation representation = lookup->representation();
645 ASSERT(!representation.IsNone()); 591 ASSERT(!representation.IsNone());
646 if (FLAG_track_fields && representation.IsSmi()) { 592 if (representation.IsSmi()) {
647 __ JumpIfNotSmi(value_reg, miss_label); 593 __ JumpIfNotSmi(value_reg, miss_label);
648 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 594 } else if (representation.IsHeapObject()) {
649 __ JumpIfSmi(value_reg, miss_label); 595 __ JumpIfSmi(value_reg, miss_label);
650 } else if (FLAG_track_double_fields && representation.IsDouble()) { 596 } else if (representation.IsDouble()) {
651 // Load the double storage. 597 // Load the double storage.
652 if (index < 0) { 598 if (index < 0) {
653 int offset = object->map()->instance_size() + (index * kPointerSize); 599 int offset = object->map()->instance_size() + (index * kPointerSize);
654 __ ldr(scratch1, FieldMemOperand(receiver_reg, offset)); 600 __ ldr(scratch1, FieldMemOperand(receiver_reg, offset));
655 } else { 601 } else {
656 __ ldr(scratch1, 602 __ ldr(scratch1,
657 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 603 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
658 int offset = index * kPointerSize + FixedArray::kHeaderSize; 604 int offset = index * kPointerSize + FixedArray::kHeaderSize;
659 __ ldr(scratch1, FieldMemOperand(scratch1, offset)); 605 __ ldr(scratch1, FieldMemOperand(scratch1, offset));
660 } 606 }
(...skipping 20 matching lines...) Expand all
681 } 627 }
682 628
683 // TODO(verwaest): Share this code as a code stub. 629 // TODO(verwaest): Share this code as a code stub.
684 SmiCheck smi_check = representation.IsTagged() 630 SmiCheck smi_check = representation.IsTagged()
685 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 631 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
686 if (index < 0) { 632 if (index < 0) {
687 // Set the property straight into the object. 633 // Set the property straight into the object.
688 int offset = object->map()->instance_size() + (index * kPointerSize); 634 int offset = object->map()->instance_size() + (index * kPointerSize);
689 __ str(value_reg, FieldMemOperand(receiver_reg, offset)); 635 __ str(value_reg, FieldMemOperand(receiver_reg, offset));
690 636
691 if (!FLAG_track_fields || !representation.IsSmi()) { 637 if (!representation.IsSmi()) {
692 // Skip updating write barrier if storing a smi. 638 // Skip updating write barrier if storing a smi.
693 __ JumpIfSmi(value_reg, &exit); 639 __ JumpIfSmi(value_reg, &exit);
694 640
695 // Update the write barrier for the array address. 641 // Update the write barrier for the array address.
696 // Pass the now unused name_reg as a scratch register. 642 // Pass the now unused name_reg as a scratch register.
697 __ mov(name_reg, value_reg); 643 __ mov(name_reg, value_reg);
698 __ RecordWriteField(receiver_reg, 644 __ RecordWriteField(receiver_reg,
699 offset, 645 offset,
700 name_reg, 646 name_reg,
701 scratch1, 647 scratch1,
702 kLRHasNotBeenSaved, 648 kLRHasNotBeenSaved,
703 kDontSaveFPRegs, 649 kDontSaveFPRegs,
704 EMIT_REMEMBERED_SET, 650 EMIT_REMEMBERED_SET,
705 smi_check); 651 smi_check);
706 } 652 }
707 } else { 653 } else {
708 // Write to the properties array. 654 // Write to the properties array.
709 int offset = index * kPointerSize + FixedArray::kHeaderSize; 655 int offset = index * kPointerSize + FixedArray::kHeaderSize;
710 // Get the properties array 656 // Get the properties array
711 __ ldr(scratch1, 657 __ ldr(scratch1,
712 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 658 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
713 __ str(value_reg, FieldMemOperand(scratch1, offset)); 659 __ str(value_reg, FieldMemOperand(scratch1, offset));
714 660
715 if (!FLAG_track_fields || !representation.IsSmi()) { 661 if (!representation.IsSmi()) {
716 // Skip updating write barrier if storing a smi. 662 // Skip updating write barrier if storing a smi.
717 __ JumpIfSmi(value_reg, &exit); 663 __ JumpIfSmi(value_reg, &exit);
718 664
719 // Update the write barrier for the array address. 665 // Update the write barrier for the array address.
720 // Ok to clobber receiver_reg and name_reg, since we return. 666 // Ok to clobber receiver_reg and name_reg, since we return.
721 __ mov(name_reg, value_reg); 667 __ mov(name_reg, value_reg);
722 __ RecordWriteField(scratch1, 668 __ RecordWriteField(scratch1,
723 offset, 669 offset,
724 name_reg, 670 name_reg,
725 receiver_reg, 671 receiver_reg,
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 // the holder and it is needed should the interceptor return without any 1101 // the holder and it is needed should the interceptor return without any
1156 // result. The CALLBACKS case needs the receiver to be passed into C++ code, 1102 // result. The CALLBACKS case needs the receiver to be passed into C++ code,
1157 // the FIELD case might cause a miss during the prototype check. 1103 // the FIELD case might cause a miss during the prototype check.
1158 bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder(); 1104 bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder();
1159 bool must_preserve_receiver_reg = !receiver().is(holder_reg) && 1105 bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
1160 (lookup->type() == CALLBACKS || must_perfrom_prototype_check); 1106 (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
1161 1107
1162 // Save necessary data before invoking an interceptor. 1108 // Save necessary data before invoking an interceptor.
1163 // Requires a frame to make GC aware of pushed pointers. 1109 // Requires a frame to make GC aware of pushed pointers.
1164 { 1110 {
1165 FrameScope frame_scope(masm(), StackFrame::INTERNAL); 1111 FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL);
1166 if (must_preserve_receiver_reg) { 1112 if (must_preserve_receiver_reg) {
1167 __ Push(receiver(), holder_reg, this->name()); 1113 __ Push(receiver(), holder_reg, this->name());
1168 } else { 1114 } else {
1169 __ Push(holder_reg, this->name()); 1115 __ Push(holder_reg, this->name());
1170 } 1116 }
1171 // Invoke an interceptor. Note: map checks from receiver to 1117 // Invoke an interceptor. Note: map checks from receiver to
1172 // interceptor's holder has been compiled before (see a caller 1118 // interceptor's holder has been compiled before (see a caller
1173 // of this method.) 1119 // of this method.)
1174 CompileCallLoadPropertyWithInterceptor( 1120 CompileCallLoadPropertyWithInterceptor(
1175 masm(), receiver(), holder_reg, this->name(), interceptor_holder, 1121 masm(), receiver(), holder_reg, this->name(), interceptor_holder,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 } 1195 }
1250 1196
1251 1197
1252 #undef __ 1198 #undef __
1253 #define __ ACCESS_MASM(masm) 1199 #define __ ACCESS_MASM(masm)
1254 1200
1255 1201
1256 void StoreStubCompiler::GenerateStoreViaSetter( 1202 void StoreStubCompiler::GenerateStoreViaSetter(
1257 MacroAssembler* masm, 1203 MacroAssembler* masm,
1258 Handle<HeapType> type, 1204 Handle<HeapType> type,
1205 Register receiver,
1259 Handle<JSFunction> setter) { 1206 Handle<JSFunction> setter) {
1260 // ----------- S t a t e ------------- 1207 // ----------- S t a t e -------------
1261 // -- r0 : value
1262 // -- r1 : receiver
1263 // -- r2 : name
1264 // -- lr : return address 1208 // -- lr : return address
1265 // ----------------------------------- 1209 // -----------------------------------
1266 { 1210 {
1267 FrameScope scope(masm, StackFrame::INTERNAL); 1211 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1268 Register receiver = r1;
1269 Register value = r0;
1270 1212
1271 // Save value register, so we can restore it later. 1213 // Save value register, so we can restore it later.
1272 __ push(value); 1214 __ push(value());
1273 1215
1274 if (!setter.is_null()) { 1216 if (!setter.is_null()) {
1275 // Call the JavaScript setter with receiver and value on the stack. 1217 // Call the JavaScript setter with receiver and value on the stack.
1276 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 1218 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
1277 // Swap in the global receiver. 1219 // Swap in the global receiver.
1278 __ ldr(receiver, 1220 __ ldr(receiver,
1279 FieldMemOperand( 1221 FieldMemOperand(
1280 receiver, JSGlobalObject::kGlobalReceiverOffset)); 1222 receiver, JSGlobalObject::kGlobalReceiverOffset));
1281 } 1223 }
1282 __ Push(receiver, value); 1224 __ Push(receiver, value());
1283 ParameterCount actual(1); 1225 ParameterCount actual(1);
1284 ParameterCount expected(setter); 1226 ParameterCount expected(setter);
1285 __ InvokeFunction(setter, expected, actual, 1227 __ InvokeFunction(setter, expected, actual,
1286 CALL_FUNCTION, NullCallWrapper()); 1228 CALL_FUNCTION, NullCallWrapper());
1287 } else { 1229 } else {
1288 // If we generate a global code snippet for deoptimization only, remember 1230 // If we generate a global code snippet for deoptimization only, remember
1289 // the place to continue after deoptimization. 1231 // the place to continue after deoptimization.
1290 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 1232 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
1291 } 1233 }
1292 1234
1293 // We have to return the passed value, not the return value of the setter. 1235 // We have to return the passed value, not the return value of the setter.
1294 __ pop(r0); 1236 __ pop(r0);
1295 1237
1296 // Restore context register. 1238 // Restore context register.
1297 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1239 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1298 } 1240 }
1299 __ Ret(); 1241 __ Ret();
1300 } 1242 }
1301 1243
1302 1244
1303 #undef __ 1245 #undef __
1304 #define __ ACCESS_MASM(masm()) 1246 #define __ ACCESS_MASM(masm())
1305 1247
1306 1248
1307 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 1249 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
1308 Handle<JSObject> object, 1250 Handle<JSObject> object,
1309 Handle<Name> name) { 1251 Handle<Name> name) {
1310 Label miss;
1311
1312 // Check that the map of the object hasn't changed.
1313 __ CheckMap(receiver(), scratch1(), Handle<Map>(object->map()), &miss,
1314 DO_SMI_CHECK);
1315
1316 // Perform global security token check if needed.
1317 if (object->IsJSGlobalProxy()) {
1318 __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss);
1319 }
1320
1321 // Stub is never generated for non-global objects that require access
1322 // checks.
1323 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
1324
1325 __ Push(receiver(), this->name(), value()); 1252 __ Push(receiver(), this->name(), value());
1326 1253
1327 // Do tail-call to the runtime system. 1254 // Do tail-call to the runtime system.
1328 ExternalReference store_ic_property = 1255 ExternalReference store_ic_property =
1329 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 1256 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
1330 __ TailCallExternalReference(store_ic_property, 3, 1); 1257 __ TailCallExternalReference(store_ic_property, 3, 1);
1331 1258
1332 // Handle store cache miss.
1333 __ bind(&miss);
1334 TailCallBuiltin(masm(), MissBuiltin(kind()));
1335
1336 // Return the generated code. 1259 // Return the generated code.
1337 return GetCode(kind(), Code::FAST, name); 1260 return GetCode(kind(), Code::FAST, name);
1338 } 1261 }
1339 1262
1340 1263
1341 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type, 1264 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type,
1342 Handle<JSObject> last, 1265 Handle<JSObject> last,
1343 Handle<Name> name) { 1266 Handle<Name> name) {
1344 NonexistentHandlerFrontend(type, last, name); 1267 NonexistentHandlerFrontend(type, last, name);
1345 1268
(...skipping 14 matching lines...) Expand all
1360 } 1283 }
1361 1284
1362 1285
1363 Register* KeyedLoadStubCompiler::registers() { 1286 Register* KeyedLoadStubCompiler::registers() {
1364 // receiver, name, scratch1, scratch2, scratch3, scratch4. 1287 // receiver, name, scratch1, scratch2, scratch3, scratch4.
1365 static Register registers[] = { r1, r0, r2, r3, r4, r5 }; 1288 static Register registers[] = { r1, r0, r2, r3, r4, r5 };
1366 return registers; 1289 return registers;
1367 } 1290 }
1368 1291
1369 1292
1293 Register StoreStubCompiler::value() {
1294 return r0;
1295 }
1296
1297
1370 Register* StoreStubCompiler::registers() { 1298 Register* StoreStubCompiler::registers() {
1371 // receiver, name, value, scratch1, scratch2, scratch3. 1299 // receiver, name, scratch1, scratch2, scratch3.
1372 static Register registers[] = { r1, r2, r0, r3, r4, r5 }; 1300 static Register registers[] = { r1, r2, r3, r4, r5 };
1373 return registers; 1301 return registers;
1374 } 1302 }
1375 1303
1376 1304
1377 Register* KeyedStoreStubCompiler::registers() { 1305 Register* KeyedStoreStubCompiler::registers() {
1378 // receiver, name, value, scratch1, scratch2, scratch3. 1306 // receiver, name, scratch1, scratch2, scratch3.
1379 static Register registers[] = { r2, r1, r0, r3, r4, r5 }; 1307 static Register registers[] = { r2, r1, r3, r4, r5 };
1380 return registers; 1308 return registers;
1381 } 1309 }
1382 1310
1383 1311
1384 #undef __ 1312 #undef __
1385 #define __ ACCESS_MASM(masm) 1313 #define __ ACCESS_MASM(masm)
1386 1314
1387 1315
1388 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 1316 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
1389 Handle<HeapType> type, 1317 Handle<HeapType> type,
1390 Register receiver, 1318 Register receiver,
1391 Handle<JSFunction> getter) { 1319 Handle<JSFunction> getter) {
1392 // ----------- S t a t e ------------- 1320 // ----------- S t a t e -------------
1393 // -- r0 : receiver 1321 // -- r0 : receiver
1394 // -- r2 : name 1322 // -- r2 : name
1395 // -- lr : return address 1323 // -- lr : return address
1396 // ----------------------------------- 1324 // -----------------------------------
1397 { 1325 {
1398 FrameScope scope(masm, StackFrame::INTERNAL); 1326 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1399 1327
1400 if (!getter.is_null()) { 1328 if (!getter.is_null()) {
1401 // Call the JavaScript getter with the receiver on the stack. 1329 // Call the JavaScript getter with the receiver on the stack.
1402 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 1330 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
1403 // Swap in the global receiver. 1331 // Swap in the global receiver.
1404 __ ldr(receiver, 1332 __ ldr(receiver,
1405 FieldMemOperand( 1333 FieldMemOperand(
1406 receiver, JSGlobalObject::kGlobalReceiverOffset)); 1334 receiver, JSGlobalObject::kGlobalReceiverOffset));
1407 } 1335 }
1408 __ push(receiver); 1336 __ push(receiver);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 // ----------------------------------- 1511 // -----------------------------------
1584 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1512 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1585 } 1513 }
1586 1514
1587 1515
1588 #undef __ 1516 #undef __
1589 1517
1590 } } // namespace v8::internal 1518 } } // namespace v8::internal
1591 1519
1592 #endif // V8_TARGET_ARCH_ARM 1520 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/array.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698