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

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 7113012: Call a stub for the write barrier on ARM. This is a step (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 6 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/code-stubs-arm.cc ('k') | src/arm/ic-arm.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 if (slot != NULL && slot->type() == Slot::CONTEXT) { 196 if (slot != NULL && slot->type() == Slot::CONTEXT) {
197 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 197 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
198 (num_parameters - 1 - i) * kPointerSize; 198 (num_parameters - 1 - i) * kPointerSize;
199 // Load parameter from stack. 199 // Load parameter from stack.
200 __ ldr(r0, MemOperand(fp, parameter_offset)); 200 __ ldr(r0, MemOperand(fp, parameter_offset));
201 // Store it in the context. 201 // Store it in the context.
202 MemOperand target = ContextOperand(cp, slot->index()); 202 MemOperand target = ContextOperand(cp, slot->index());
203 __ str(r0, target); 203 __ str(r0, target);
204 204
205 // Update the write barrier. 205 // Update the write barrier.
206 __ RecordWriteContextSlot(cp, target.offset(), r0, r3, kDontSaveFPRegs); 206 __ RecordWriteContextSlot(
207 cp, target.offset(), r0, r3, kLRHasBeenSaved, kDontSaveFPRegs);
207 } 208 }
208 } 209 }
209 } 210 }
210 211
211 Variable* arguments = scope()->arguments(); 212 Variable* arguments = scope()->arguments();
212 if (arguments != NULL) { 213 if (arguments != NULL) {
213 // Function uses arguments object. 214 // Function uses arguments object.
214 Comment cmnt(masm_, "[ Allocate arguments object"); 215 Comment cmnt(masm_, "[ Allocate arguments object");
215 if (!function_in_register) { 216 if (!function_in_register) {
216 // Load this again, if it's used by the local context below. 217 // Load this again, if it's used by the local context below.
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 Register src, 642 Register src,
642 Register scratch1, 643 Register scratch1,
643 Register scratch2) { 644 Register scratch2) {
644 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented. 645 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented.
645 ASSERT(!scratch1.is(src) && !scratch2.is(src)); 646 ASSERT(!scratch1.is(src) && !scratch2.is(src));
646 MemOperand location = EmitSlotSearch(dst, scratch1); 647 MemOperand location = EmitSlotSearch(dst, scratch1);
647 __ str(src, location); 648 __ str(src, location);
648 649
649 // Emit the write barrier code if the location is in the heap. 650 // Emit the write barrier code if the location is in the heap.
650 if (dst->type() == Slot::CONTEXT) { 651 if (dst->type() == Slot::CONTEXT) {
651 __ RecordWriteContextSlot( 652 __ RecordWriteContextSlot(scratch1,
652 scratch1, location.offset(), src, scratch2, kDontSaveFPRegs); 653 location.offset(),
654 src,
655 scratch2,
656 kLRHasBeenSaved,
657 kDontSaveFPRegs);
653 } 658 }
654 } 659 }
655 660
656 661
657 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state, 662 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state,
658 bool should_normalize, 663 bool should_normalize,
659 Label* if_true, 664 Label* if_true,
660 Label* if_false) { 665 Label* if_false) {
661 // Only prepare for bailouts before splits if we're in a test 666 // Only prepare for bailouts before splits if we're in a test
662 // context. Otherwise, we let the Visit function deal with the 667 // context. Otherwise, we let the Visit function deal with the
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 } else if (function != NULL) { 727 } else if (function != NULL) {
723 VisitForAccumulatorValue(function); 728 VisitForAccumulatorValue(function);
724 MemOperand target = ContextOperand(cp, slot->index()); 729 MemOperand target = ContextOperand(cp, slot->index());
725 __ str(result_register(), target); 730 __ str(result_register(), target);
726 731
727 // We know that we have written a function, which is not a smi. 732 // We know that we have written a function, which is not a smi.
728 __ RecordWriteContextSlot(cp, 733 __ RecordWriteContextSlot(cp,
729 target.offset(), 734 target.offset(),
730 result_register(), 735 result_register(),
731 r2, 736 r2,
737 kLRHasBeenSaved,
732 kDontSaveFPRegs, 738 kDontSaveFPRegs,
733 EMIT_REMEMBERED_SET, 739 EMIT_REMEMBERED_SET,
734 OMIT_SMI_CHECK); 740 OMIT_SMI_CHECK);
735 } 741 }
736 break; 742 break;
737 743
738 case Slot::LOOKUP: { 744 case Slot::LOOKUP: {
739 __ mov(r2, Operand(variable->name())); 745 __ mov(r2, Operand(variable->name()));
740 // Declaration nodes are always introduced in one of two modes. 746 // Declaration nodes are always introduced in one of two modes.
741 ASSERT(mode == Variable::VAR || 747 ASSERT(mode == Variable::VAR ||
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 VisitForAccumulatorValue(subexpr); 1552 VisitForAccumulatorValue(subexpr);
1547 1553
1548 // Store the subexpression value in the array's elements. 1554 // Store the subexpression value in the array's elements.
1549 __ ldr(r1, MemOperand(sp)); // Copy of array literal. 1555 __ ldr(r1, MemOperand(sp)); // Copy of array literal.
1550 __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset)); 1556 __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
1551 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1557 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1552 __ str(result_register(), FieldMemOperand(r1, offset)); 1558 __ str(result_register(), FieldMemOperand(r1, offset));
1553 1559
1554 // Update the write barrier for the array store with r0 as the scratch 1560 // Update the write barrier for the array store with r0 as the scratch
1555 // register. 1561 // register.
1556 __ RecordWriteField(r1, offset, result_register(), r2, kDontSaveFPRegs); 1562 __ RecordWriteField(
1563 r1, offset, result_register(), r2, kLRHasBeenSaved, kDontSaveFPRegs);
1557 1564
1558 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1565 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1559 } 1566 }
1560 1567
1561 if (result_saved) { 1568 if (result_saved) {
1562 context()->PlugTOS(); 1569 context()->PlugTOS();
1563 } else { 1570 } else {
1564 context()->Plug(r0); 1571 context()->Plug(r0);
1565 } 1572 }
1566 } 1573 }
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 break; 1935 break;
1929 case Slot::CONTEXT: { 1936 case Slot::CONTEXT: {
1930 __ ldr(r1, ContextOperand(cp, Context::FCONTEXT_INDEX)); 1937 __ ldr(r1, ContextOperand(cp, Context::FCONTEXT_INDEX));
1931 __ ldr(r2, ContextOperand(r1, slot->index())); 1938 __ ldr(r2, ContextOperand(r1, slot->index()));
1932 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 1939 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
1933 __ cmp(r2, ip); 1940 __ cmp(r2, ip);
1934 __ b(ne, &skip); 1941 __ b(ne, &skip);
1935 MemOperand target = ContextOperand(r1, slot->index()); 1942 MemOperand target = ContextOperand(r1, slot->index());
1936 __ str(r0, target); 1943 __ str(r0, target);
1937 __ mov(r3, r0); // Preserve the stored value in r0. 1944 __ mov(r3, r0); // Preserve the stored value in r0.
1938 __ RecordWriteContextSlot(r1, target.offset(), r3, r2, kDontSaveFPRegs); 1945 __ RecordWriteContextSlot(
1946 r1, target.offset(), r3, r2, kLRHasBeenSaved, kDontSaveFPRegs);
1939 break; 1947 break;
1940 } 1948 }
1941 case Slot::LOOKUP: 1949 case Slot::LOOKUP:
1942 __ push(r0); 1950 __ push(r0);
1943 __ mov(r0, Operand(slot->var()->name())); 1951 __ mov(r0, Operand(slot->var()->name()));
1944 __ Push(cp, r0); // Context and name. 1952 __ Push(cp, r0); // Context and name.
1945 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 1953 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1946 break; 1954 break;
1947 } 1955 }
1948 __ bind(&skip); 1956 __ bind(&skip);
1949 1957
1950 } else if (var->mode() != Variable::CONST) { 1958 } else if (var->mode() != Variable::CONST) {
1951 // Perform the assignment for non-const variables. Const assignments 1959 // Perform the assignment for non-const variables. Const assignments
1952 // are simply skipped. 1960 // are simply skipped.
1953 Slot* slot = var->AsSlot(); 1961 Slot* slot = var->AsSlot();
1954 switch (slot->type()) { 1962 switch (slot->type()) {
1955 case Slot::PARAMETER: 1963 case Slot::PARAMETER:
1956 case Slot::LOCAL: 1964 case Slot::LOCAL:
1957 // Perform the assignment. 1965 // Perform the assignment.
1958 __ str(result_register(), MemOperand(fp, SlotOffset(slot))); 1966 __ str(result_register(), MemOperand(fp, SlotOffset(slot)));
1959 break; 1967 break;
1960 1968
1961 case Slot::CONTEXT: { 1969 case Slot::CONTEXT: {
1962 MemOperand target = EmitSlotSearch(slot, r1); 1970 MemOperand target = EmitSlotSearch(slot, r1);
1963 // Perform the assignment and issue the write barrier. 1971 // Perform the assignment and issue the write barrier.
1964 __ str(result_register(), target); 1972 __ str(result_register(), target);
1965 // The value of the assignment is in result_register(). RecordWrite 1973 // The value of the assignment is in result_register(). RecordWrite
1966 // clobbers its second and third register arguments. 1974 // clobbers its second and third register arguments.
1967 __ mov(r3, result_register()); 1975 __ mov(r3, result_register());
1968 __ RecordWriteContextSlot(r1, target.offset(), r3, r2, kDontSaveFPRegs); 1976 __ RecordWriteContextSlot(
1977 r1, target.offset(), r3, r2, kLRHasBeenSaved, kDontSaveFPRegs);
1969 break; 1978 break;
1970 } 1979 }
1971 1980
1972 case Slot::LOOKUP: 1981 case Slot::LOOKUP:
1973 // Call the runtime for the assignment. 1982 // Call the runtime for the assignment.
1974 __ push(r0); // Value. 1983 __ push(r0); // Value.
1975 __ mov(r1, Operand(slot->var()->name())); 1984 __ mov(r1, Operand(slot->var()->name()));
1976 __ mov(r0, Operand(Smi::FromInt(strict_mode_flag()))); 1985 __ mov(r0, Operand(Smi::FromInt(strict_mode_flag())));
1977 __ Push(cp, r1, r0); // Context, name, strict mode. 1986 __ Push(cp, r1, r0); // Context, name, strict mode.
1978 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1987 __ CallRuntime(Runtime::kStoreContextSlot, 4);
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after
2962 2971
2963 // If the object is not a value type, return the value. 2972 // If the object is not a value type, return the value.
2964 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); 2973 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE);
2965 __ b(ne, &done); 2974 __ b(ne, &done);
2966 2975
2967 // Store the value. 2976 // Store the value.
2968 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); 2977 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset));
2969 // Update the write barrier. Save the value as it will be 2978 // Update the write barrier. Save the value as it will be
2970 // overwritten by the write barrier code and is needed afterward. 2979 // overwritten by the write barrier code and is needed afterward.
2971 __ mov(r2, r0); 2980 __ mov(r2, r0);
2972 __ RecordWriteField(r1, JSValue::kValueOffset, r2, r3, kDontSaveFPRegs); 2981 __ RecordWriteField(
2982 r1, JSValue::kValueOffset, r2, r3, kLRHasBeenSaved, kDontSaveFPRegs);
2973 2983
2974 __ bind(&done); 2984 __ bind(&done);
2975 context()->Plug(r0); 2985 context()->Plug(r0);
2976 } 2986 }
2977 2987
2978 2988
2979 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { 2989 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
2980 ASSERT_EQ(args->length(), 1); 2990 ASSERT_EQ(args->length(), 1);
2981 2991
2982 // Load the argument on the stack and call the stub. 2992 // Load the argument on the stack and call the stub.
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
3258 3268
3259 Label no_remembered_set; 3269 Label no_remembered_set;
3260 __ CheckPageFlag(elements, 3270 __ CheckPageFlag(elements,
3261 scratch1, 3271 scratch1,
3262 MemoryChunk::SCAN_ON_SCAVENGE, 3272 MemoryChunk::SCAN_ON_SCAVENGE,
3263 ne, 3273 ne,
3264 &no_remembered_set); 3274 &no_remembered_set);
3265 // Possible optimization: do a check that both values are Smis 3275 // Possible optimization: do a check that both values are Smis
3266 // (or them and test against Smi mask.) 3276 // (or them and test against Smi mask.)
3267 3277
3268 __ RememberedSetHelper(index1, scratch2, kDontSaveFPRegs); 3278 __ RememberedSetHelper(
3269 __ RememberedSetHelper(index2, scratch2, kDontSaveFPRegs); 3279 index1, scratch2, kDontSaveFPRegs, MacroAssembler::kFallThroughAtEnd);
3280 __ RememberedSetHelper(
3281 index2, scratch2, kDontSaveFPRegs, MacroAssembler::kFallThroughAtEnd);
3270 3282
3271 __ bind(&no_remembered_set); 3283 __ bind(&no_remembered_set);
3272 // We are done. Drop elements from the stack, and return undefined. 3284 // We are done. Drop elements from the stack, and return undefined.
3273 __ Drop(3); 3285 __ Drop(3);
3274 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 3286 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
3275 __ jmp(&done); 3287 __ jmp(&done);
3276 3288
3277 __ bind(&slow_case); 3289 __ bind(&slow_case);
3278 __ CallRuntime(Runtime::kSwapElements, 3); 3290 __ CallRuntime(Runtime::kSwapElements, 3);
3279 3291
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
4374 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 4386 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4375 __ add(pc, r1, Operand(masm_->CodeObject())); 4387 __ add(pc, r1, Operand(masm_->CodeObject()));
4376 } 4388 }
4377 4389
4378 4390
4379 #undef __ 4391 #undef __
4380 4392
4381 } } // namespace v8::internal 4393 } } // namespace v8::internal
4382 4394
4383 #endif // V8_TARGET_ARCH_ARM 4395 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698