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

Side by Side Diff: src/runtime.cc

Issue 558041: RFC: Try to be much more careful with where we skip the write barrier by:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 10 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/objects-inl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 StackLimitCheck check; 100 StackLimitCheck check;
101 if (check.HasOverflowed()) return Top::StackOverflow(); 101 if (check.HasOverflowed()) return Top::StackOverflow();
102 102
103 Object* result = Heap::CopyJSObject(boilerplate); 103 Object* result = Heap::CopyJSObject(boilerplate);
104 if (result->IsFailure()) return result; 104 if (result->IsFailure()) return result;
105 JSObject* copy = JSObject::cast(result); 105 JSObject* copy = JSObject::cast(result);
106 106
107 // Deep copy local properties. 107 // Deep copy local properties.
108 if (copy->HasFastProperties()) { 108 if (copy->HasFastProperties()) {
109 FixedArray* properties = copy->properties(); 109 FixedArray* properties = copy->properties();
110 WriteBarrierMode mode = properties->GetWriteBarrierMode();
111 for (int i = 0; i < properties->length(); i++) { 110 for (int i = 0; i < properties->length(); i++) {
112 Object* value = properties->get(i); 111 Object* value = properties->get(i);
113 if (value->IsJSObject()) { 112 if (value->IsJSObject()) {
114 JSObject* jsObject = JSObject::cast(value); 113 JSObject* js_object = JSObject::cast(value);
115 result = DeepCopyBoilerplate(jsObject); 114 result = DeepCopyBoilerplate(js_object);
116 if (result->IsFailure()) return result; 115 if (result->IsFailure()) return result;
117 properties->set(i, result, mode); 116 properties->set(i, result);
118 } 117 }
119 } 118 }
120 mode = copy->GetWriteBarrierMode();
121 int nof = copy->map()->inobject_properties(); 119 int nof = copy->map()->inobject_properties();
122 for (int i = 0; i < nof; i++) { 120 for (int i = 0; i < nof; i++) {
123 Object* value = copy->InObjectPropertyAt(i); 121 Object* value = copy->InObjectPropertyAt(i);
124 if (value->IsJSObject()) { 122 if (value->IsJSObject()) {
125 JSObject* jsObject = JSObject::cast(value); 123 JSObject* js_object = JSObject::cast(value);
126 result = DeepCopyBoilerplate(jsObject); 124 result = DeepCopyBoilerplate(js_object);
127 if (result->IsFailure()) return result; 125 if (result->IsFailure()) return result;
128 copy->InObjectPropertyAtPut(i, result, mode); 126 copy->InObjectPropertyAtPut(i, result);
129 } 127 }
130 } 128 }
131 } else { 129 } else {
132 result = Heap::AllocateFixedArray(copy->NumberOfLocalProperties(NONE)); 130 result = Heap::AllocateFixedArray(copy->NumberOfLocalProperties(NONE));
133 if (result->IsFailure()) return result; 131 if (result->IsFailure()) return result;
134 FixedArray* names = FixedArray::cast(result); 132 FixedArray* names = FixedArray::cast(result);
135 copy->GetLocalPropertyNames(names, 0); 133 copy->GetLocalPropertyNames(names, 0);
136 for (int i = 0; i < names->length(); i++) { 134 for (int i = 0; i < names->length(); i++) {
137 ASSERT(names->get(i)->IsString()); 135 ASSERT(names->get(i)->IsString());
138 String* keyString = String::cast(names->get(i)); 136 String* key_string = String::cast(names->get(i));
139 PropertyAttributes attributes = 137 PropertyAttributes attributes =
140 copy->GetLocalPropertyAttribute(keyString); 138 copy->GetLocalPropertyAttribute(key_string);
141 // Only deep copy fields from the object literal expression. 139 // Only deep copy fields from the object literal expression.
142 // In particular, don't try to copy the length attribute of 140 // In particular, don't try to copy the length attribute of
143 // an array. 141 // an array.
144 if (attributes != NONE) continue; 142 if (attributes != NONE) continue;
145 Object* value = copy->GetProperty(keyString, &attributes); 143 Object* value = copy->GetProperty(key_string, &attributes);
146 ASSERT(!value->IsFailure()); 144 ASSERT(!value->IsFailure());
147 if (value->IsJSObject()) { 145 if (value->IsJSObject()) {
148 JSObject* jsObject = JSObject::cast(value); 146 JSObject* js_object = JSObject::cast(value);
149 result = DeepCopyBoilerplate(jsObject); 147 result = DeepCopyBoilerplate(js_object);
150 if (result->IsFailure()) return result; 148 if (result->IsFailure()) return result;
151 result = copy->SetProperty(keyString, result, NONE); 149 result = copy->SetProperty(key_string, result, NONE);
152 if (result->IsFailure()) return result; 150 if (result->IsFailure()) return result;
153 } 151 }
154 } 152 }
155 } 153 }
156 154
157 // Deep copy local elements. 155 // Deep copy local elements.
158 // Pixel elements cannot be created using an object literal. 156 // Pixel elements cannot be created using an object literal.
159 ASSERT(!copy->HasPixelElements() && !copy->HasExternalArrayElements()); 157 ASSERT(!copy->HasPixelElements() && !copy->HasExternalArrayElements());
160 switch (copy->GetElementsKind()) { 158 switch (copy->GetElementsKind()) {
161 case JSObject::FAST_ELEMENTS: { 159 case JSObject::FAST_ELEMENTS: {
162 FixedArray* elements = FixedArray::cast(copy->elements()); 160 FixedArray* elements = FixedArray::cast(copy->elements());
163 WriteBarrierMode mode = elements->GetWriteBarrierMode();
164 for (int i = 0; i < elements->length(); i++) { 161 for (int i = 0; i < elements->length(); i++) {
165 Object* value = elements->get(i); 162 Object* value = elements->get(i);
166 if (value->IsJSObject()) { 163 if (value->IsJSObject()) {
167 JSObject* jsObject = JSObject::cast(value); 164 JSObject* js_object = JSObject::cast(value);
168 result = DeepCopyBoilerplate(jsObject); 165 result = DeepCopyBoilerplate(js_object);
169 if (result->IsFailure()) return result; 166 if (result->IsFailure()) return result;
170 elements->set(i, result, mode); 167 elements->set(i, result);
171 } 168 }
172 } 169 }
173 break; 170 break;
174 } 171 }
175 case JSObject::DICTIONARY_ELEMENTS: { 172 case JSObject::DICTIONARY_ELEMENTS: {
176 NumberDictionary* element_dictionary = copy->element_dictionary(); 173 NumberDictionary* element_dictionary = copy->element_dictionary();
177 int capacity = element_dictionary->Capacity(); 174 int capacity = element_dictionary->Capacity();
178 for (int i = 0; i < capacity; i++) { 175 for (int i = 0; i < capacity; i++) {
179 Object* k = element_dictionary->KeyAt(i); 176 Object* k = element_dictionary->KeyAt(i);
180 if (element_dictionary->IsKey(k)) { 177 if (element_dictionary->IsKey(k)) {
181 Object* value = element_dictionary->ValueAt(i); 178 Object* value = element_dictionary->ValueAt(i);
182 if (value->IsJSObject()) { 179 if (value->IsJSObject()) {
183 JSObject* jsObject = JSObject::cast(value); 180 JSObject* js_object = JSObject::cast(value);
184 result = DeepCopyBoilerplate(jsObject); 181 result = DeepCopyBoilerplate(js_object);
185 if (result->IsFailure()) return result; 182 if (result->IsFailure()) return result;
186 element_dictionary->ValueAtPut(i, result); 183 element_dictionary->ValueAtPut(i, result);
187 } 184 }
188 } 185 }
189 } 186 }
190 break; 187 break;
191 } 188 }
192 default: 189 default:
193 UNREACHABLE(); 190 UNREACHABLE();
194 break; 191 break;
(...skipping 1235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 int number_of_literals = fun->NumberOfLiterals(); 1427 int number_of_literals = fun->NumberOfLiterals();
1431 Handle<FixedArray> literals = 1428 Handle<FixedArray> literals =
1432 Factory::NewFixedArray(number_of_literals, TENURED); 1429 Factory::NewFixedArray(number_of_literals, TENURED);
1433 if (number_of_literals > 0) { 1430 if (number_of_literals > 0) {
1434 // Insert the object, regexp and array functions in the literals 1431 // Insert the object, regexp and array functions in the literals
1435 // array prefix. These are the functions that will be used when 1432 // array prefix. These are the functions that will be used when
1436 // creating object, regexp and array literals. 1433 // creating object, regexp and array literals.
1437 literals->set(JSFunction::kLiteralGlobalContextIndex, 1434 literals->set(JSFunction::kLiteralGlobalContextIndex,
1438 context->global_context()); 1435 context->global_context());
1439 } 1436 }
1437 // It's okay to skip the write barrier here because the literals
1438 // are guaranteed to be in old space.
1440 target->set_literals(*literals, SKIP_WRITE_BARRIER); 1439 target->set_literals(*literals, SKIP_WRITE_BARRIER);
1441 } 1440 }
1442 1441
1443 target->set_context(*context); 1442 target->set_context(*context);
1444 return *target; 1443 return *target;
1445 } 1444 }
1446 1445
1447 1446
1448 static Object* CharCodeAt(String* subject, Object* index) { 1447 static Object* CharCodeAt(String* subject, Object* index) {
1449 uint32_t i = 0; 1448 uint32_t i = 0;
(...skipping 3258 matching lines...) Expand 10 before | Expand all | Expand 10 after
4708 JavaScriptFrame* frame = it.frame(); 4707 JavaScriptFrame* frame = it.frame();
4709 4708
4710 const int length = frame->GetProvidedParametersCount(); 4709 const int length = frame->GetProvidedParametersCount();
4711 Object* result = Heap::AllocateArgumentsObject(callee, length); 4710 Object* result = Heap::AllocateArgumentsObject(callee, length);
4712 if (result->IsFailure()) return result; 4711 if (result->IsFailure()) return result;
4713 if (length > 0) { 4712 if (length > 0) {
4714 Object* obj = Heap::AllocateFixedArray(length); 4713 Object* obj = Heap::AllocateFixedArray(length);
4715 if (obj->IsFailure()) return obj; 4714 if (obj->IsFailure()) return obj;
4716 FixedArray* array = FixedArray::cast(obj); 4715 FixedArray* array = FixedArray::cast(obj);
4717 ASSERT(array->length() == length); 4716 ASSERT(array->length() == length);
4718 WriteBarrierMode mode = array->GetWriteBarrierMode(); 4717
4718 AssertNoAllocation no_gc;
4719 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
4719 for (int i = 0; i < length; i++) { 4720 for (int i = 0; i < length; i++) {
4720 array->set(i, frame->GetParameter(i), mode); 4721 array->set(i, frame->GetParameter(i), mode);
4721 } 4722 }
4722 JSObject::cast(result)->set_elements(array); 4723 JSObject::cast(result)->set_elements(array);
4723 } 4724 }
4724 return result; 4725 return result;
4725 } 4726 }
4726 4727
4727 4728
4728 static Object* Runtime_NewArgumentsFast(Arguments args) { 4729 static Object* Runtime_NewArgumentsFast(Arguments args) {
4729 NoHandleAllocation ha; 4730 NoHandleAllocation ha;
4730 ASSERT(args.length() == 3); 4731 ASSERT(args.length() == 3);
4731 4732
4732 JSFunction* callee = JSFunction::cast(args[0]); 4733 JSFunction* callee = JSFunction::cast(args[0]);
4733 Object** parameters = reinterpret_cast<Object**>(args[1]); 4734 Object** parameters = reinterpret_cast<Object**>(args[1]);
4734 const int length = Smi::cast(args[2])->value(); 4735 const int length = Smi::cast(args[2])->value();
4735 4736
4736 Object* result = Heap::AllocateArgumentsObject(callee, length); 4737 Object* result = Heap::AllocateArgumentsObject(callee, length);
4737 if (result->IsFailure()) return result; 4738 if (result->IsFailure()) return result;
4738 // Allocate the elements if needed. 4739 // Allocate the elements if needed.
4739 if (length > 0) { 4740 if (length > 0) {
4740 // Allocate the fixed array. 4741 // Allocate the fixed array.
4741 Object* obj = Heap::AllocateRawFixedArray(length); 4742 Object* obj = Heap::AllocateRawFixedArray(length);
4742 if (obj->IsFailure()) return obj; 4743 if (obj->IsFailure()) return obj;
4744
4745 AssertNoAllocation no_gc;
4743 reinterpret_cast<Array*>(obj)->set_map(Heap::fixed_array_map()); 4746 reinterpret_cast<Array*>(obj)->set_map(Heap::fixed_array_map());
4744 FixedArray* array = FixedArray::cast(obj); 4747 FixedArray* array = FixedArray::cast(obj);
4745 array->set_length(length); 4748 array->set_length(length);
4746 WriteBarrierMode mode = array->GetWriteBarrierMode(); 4749
4750 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
4747 for (int i = 0; i < length; i++) { 4751 for (int i = 0; i < length; i++) {
4748 array->set(i, *--parameters, mode); 4752 array->set(i, *--parameters, mode);
4749 } 4753 }
4750 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); 4754 JSObject::cast(result)->set_elements(FixedArray::cast(obj));
4751 } 4755 }
4752 return result; 4756 return result;
4753 } 4757 }
4754 4758
4755 4759
4756 static Object* Runtime_NewClosure(Arguments args) { 4760 static Object* Runtime_NewClosure(Arguments args) {
(...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after
6025 6029
6026 6030
6027 // Move contents of argument 0 (an array) to argument 1 (an array) 6031 // Move contents of argument 0 (an array) to argument 1 (an array)
6028 static Object* Runtime_MoveArrayContents(Arguments args) { 6032 static Object* Runtime_MoveArrayContents(Arguments args) {
6029 ASSERT(args.length() == 2); 6033 ASSERT(args.length() == 2);
6030 CONVERT_CHECKED(JSArray, from, args[0]); 6034 CONVERT_CHECKED(JSArray, from, args[0]);
6031 CONVERT_CHECKED(JSArray, to, args[1]); 6035 CONVERT_CHECKED(JSArray, to, args[1]);
6032 to->SetContent(FixedArray::cast(from->elements())); 6036 to->SetContent(FixedArray::cast(from->elements()));
6033 to->set_length(from->length()); 6037 to->set_length(from->length());
6034 from->SetContent(Heap::empty_fixed_array()); 6038 from->SetContent(Heap::empty_fixed_array());
6035 from->set_length(0); 6039 from->set_length(Smi::FromInt(0));
6036 return to; 6040 return to;
6037 } 6041 }
6038 6042
6039 6043
6040 // How many elements does this array have? 6044 // How many elements does this array have?
6041 static Object* Runtime_EstimateNumberOfElements(Arguments args) { 6045 static Object* Runtime_EstimateNumberOfElements(Arguments args) {
6042 ASSERT(args.length() == 1); 6046 ASSERT(args.length() == 1);
6043 CONVERT_CHECKED(JSArray, array, args[0]); 6047 CONVERT_CHECKED(JSArray, array, args[0]);
6044 HeapObject* elements = array->elements(); 6048 HeapObject* elements = array->elements();
6045 if (elements->IsDictionary()) { 6049 if (elements->IsDictionary()) {
(...skipping 22 matching lines...) Expand all
6068 uint32_t index; 6072 uint32_t index;
6069 if (!Array::IndexFromObject(key, &index) || index >= length) { 6073 if (!Array::IndexFromObject(key, &index) || index >= length) {
6070 // Zap invalid keys. 6074 // Zap invalid keys.
6071 keys->set_undefined(i); 6075 keys->set_undefined(i);
6072 } 6076 }
6073 } 6077 }
6074 return *Factory::NewJSArrayWithElements(keys); 6078 return *Factory::NewJSArrayWithElements(keys);
6075 } else { 6079 } else {
6076 Handle<FixedArray> single_interval = Factory::NewFixedArray(2); 6080 Handle<FixedArray> single_interval = Factory::NewFixedArray(2);
6077 // -1 means start of array. 6081 // -1 means start of array.
6078 single_interval->set(0, 6082 single_interval->set(0, Smi::FromInt(-1));
6079 Smi::FromInt(-1),
6080 SKIP_WRITE_BARRIER);
6081 uint32_t actual_length = static_cast<uint32_t>(array->elements()->length()); 6083 uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
6082 uint32_t min_length = actual_length < length ? actual_length : length; 6084 uint32_t min_length = actual_length < length ? actual_length : length;
6083 Handle<Object> length_object = 6085 Handle<Object> length_object =
6084 Factory::NewNumber(static_cast<double>(min_length)); 6086 Factory::NewNumber(static_cast<double>(min_length));
6085 single_interval->set(1, *length_object); 6087 single_interval->set(1, *length_object);
6086 return *Factory::NewJSArrayWithElements(single_interval); 6088 return *Factory::NewJSArrayWithElements(single_interval);
6087 } 6089 }
6088 } 6090 }
6089 6091
6090 6092
(...skipping 1352 matching lines...) Expand 10 before | Expand all | Expand 10 after
7443 index = ScopeInfo<>::ContextSlotIndex(*code, Heap::arguments_symbol(), 7445 index = ScopeInfo<>::ContextSlotIndex(*code, Heap::arguments_symbol(),
7444 NULL); 7446 NULL);
7445 if (index != -1) { 7447 if (index != -1) {
7446 return Handle<Object>(function_context->get(index)); 7448 return Handle<Object>(function_context->get(index));
7447 } 7449 }
7448 } 7450 }
7449 7451
7450 const int length = frame->GetProvidedParametersCount(); 7452 const int length = frame->GetProvidedParametersCount();
7451 Handle<JSObject> arguments = Factory::NewArgumentsObject(function, length); 7453 Handle<JSObject> arguments = Factory::NewArgumentsObject(function, length);
7452 Handle<FixedArray> array = Factory::NewFixedArray(length); 7454 Handle<FixedArray> array = Factory::NewFixedArray(length);
7453 WriteBarrierMode mode = array->GetWriteBarrierMode(); 7455
7456 AssertNoAllocation no_gc;
7457 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
7454 for (int i = 0; i < length; i++) { 7458 for (int i = 0; i < length; i++) {
7455 array->set(i, frame->GetParameter(i), mode); 7459 array->set(i, frame->GetParameter(i), mode);
7456 } 7460 }
7457 arguments->set_elements(*array); 7461 arguments->set_elements(*array);
7458 return arguments; 7462 return arguments;
7459 } 7463 }
7460 7464
7461 7465
7462 // Evaluate a piece of JavaScript in the context of a stack frame for 7466 // Evaluate a piece of JavaScript in the context of a stack frame for
7463 // debugging. This is accomplished by creating a new context which in its 7467 // debugging. This is accomplished by creating a new context which in its
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
8025 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); 8029 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
8026 Object* recv = frame->receiver(); 8030 Object* recv = frame->receiver();
8027 Object* fun = frame->function(); 8031 Object* fun = frame->function();
8028 Address pc = frame->pc(); 8032 Address pc = frame->pc();
8029 Address start = frame->code()->address(); 8033 Address start = frame->code()->address();
8030 Smi* offset = Smi::FromInt(static_cast<int>(pc - start)); 8034 Smi* offset = Smi::FromInt(static_cast<int>(pc - start));
8031 FixedArray* elements = FixedArray::cast(result->elements()); 8035 FixedArray* elements = FixedArray::cast(result->elements());
8032 if (cursor + 2 < elements->length()) { 8036 if (cursor + 2 < elements->length()) {
8033 elements->set(cursor++, recv); 8037 elements->set(cursor++, recv);
8034 elements->set(cursor++, fun); 8038 elements->set(cursor++, fun);
8035 elements->set(cursor++, offset, SKIP_WRITE_BARRIER); 8039 elements->set(cursor++, offset);
8036 } else { 8040 } else {
8037 HandleScope scope; 8041 HandleScope scope;
8038 Handle<Object> recv_handle(recv); 8042 Handle<Object> recv_handle(recv);
8039 Handle<Object> fun_handle(fun); 8043 Handle<Object> fun_handle(fun);
8040 SetElement(result, cursor++, recv_handle); 8044 SetElement(result, cursor++, recv_handle);
8041 SetElement(result, cursor++, fun_handle); 8045 SetElement(result, cursor++, fun_handle);
8042 SetElement(result, cursor++, Handle<Smi>(offset)); 8046 SetElement(result, cursor++, Handle<Smi>(offset));
8043 } 8047 }
8044 } 8048 }
8045 iter.Advance(); 8049 iter.Advance();
8046 } 8050 }
8047 8051
8048 result->set_length(Smi::FromInt(cursor), SKIP_WRITE_BARRIER); 8052 result->set_length(Smi::FromInt(cursor));
8049
8050 return *result; 8053 return *result;
8051 } 8054 }
8052 8055
8053 8056
8054 // Returns V8 version as a string. 8057 // Returns V8 version as a string.
8055 static Object* Runtime_GetV8Version(Arguments args) { 8058 static Object* Runtime_GetV8Version(Arguments args) {
8056 ASSERT_EQ(args.length(), 0); 8059 ASSERT_EQ(args.length(), 0);
8057 8060
8058 NoHandleAllocation ha; 8061 NoHandleAllocation ha;
8059 8062
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
8163 } else { 8166 } else {
8164 // Handle last resort GC and make sure to allow future allocations 8167 // Handle last resort GC and make sure to allow future allocations
8165 // to grow the heap without causing GCs (if possible). 8168 // to grow the heap without causing GCs (if possible).
8166 Counters::gc_last_resort_from_js.Increment(); 8169 Counters::gc_last_resort_from_js.Increment();
8167 Heap::CollectAllGarbage(false); 8170 Heap::CollectAllGarbage(false);
8168 } 8171 }
8169 } 8172 }
8170 8173
8171 8174
8172 } } // namespace v8::internal 8175 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698