OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 } | 212 } |
213 } | 213 } |
214 | 214 |
215 bool function_in_register = true; | 215 bool function_in_register = true; |
216 | 216 |
217 // Possibly allocate a local context. | 217 // Possibly allocate a local context. |
218 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 218 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
219 if (heap_slots > 0) { | 219 if (heap_slots > 0) { |
220 Comment cmnt(masm_, "[ Allocate context"); | 220 Comment cmnt(masm_, "[ Allocate context"); |
221 // Argument to NewContext is the function, which is still in a1. | 221 // Argument to NewContext is the function, which is still in a1. |
| 222 bool need_write_barrier = true; |
222 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { | 223 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { |
223 __ push(a1); | 224 __ push(a1); |
224 __ Push(info->scope()->GetScopeInfo()); | 225 __ Push(info->scope()->GetScopeInfo()); |
225 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); | 226 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); |
226 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 227 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
227 FastNewContextStub stub(isolate(), heap_slots); | 228 FastNewContextStub stub(isolate(), heap_slots); |
228 __ CallStub(&stub); | 229 __ CallStub(&stub); |
| 230 // Result of FastNewContextStub is always in new space. |
| 231 need_write_barrier = false; |
229 } else { | 232 } else { |
230 __ push(a1); | 233 __ push(a1); |
231 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); | 234 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
232 } | 235 } |
233 function_in_register = false; | 236 function_in_register = false; |
234 // Context is returned in v0. It replaces the context passed to us. | 237 // Context is returned in v0. It replaces the context passed to us. |
235 // It's saved in the stack and kept live in cp. | 238 // It's saved in the stack and kept live in cp. |
236 __ mov(cp, v0); | 239 __ mov(cp, v0); |
237 __ sw(v0, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 240 __ sw(v0, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
238 // Copy any necessary parameters into the context. | 241 // Copy any necessary parameters into the context. |
239 int num_parameters = info->scope()->num_parameters(); | 242 int num_parameters = info->scope()->num_parameters(); |
240 for (int i = 0; i < num_parameters; i++) { | 243 for (int i = 0; i < num_parameters; i++) { |
241 Variable* var = scope()->parameter(i); | 244 Variable* var = scope()->parameter(i); |
242 if (var->IsContextSlot()) { | 245 if (var->IsContextSlot()) { |
243 int parameter_offset = StandardFrameConstants::kCallerSPOffset + | 246 int parameter_offset = StandardFrameConstants::kCallerSPOffset + |
244 (num_parameters - 1 - i) * kPointerSize; | 247 (num_parameters - 1 - i) * kPointerSize; |
245 // Load parameter from stack. | 248 // Load parameter from stack. |
246 __ lw(a0, MemOperand(fp, parameter_offset)); | 249 __ lw(a0, MemOperand(fp, parameter_offset)); |
247 // Store it in the context. | 250 // Store it in the context. |
248 MemOperand target = ContextOperand(cp, var->index()); | 251 MemOperand target = ContextOperand(cp, var->index()); |
249 __ sw(a0, target); | 252 __ sw(a0, target); |
250 | 253 |
251 // Update the write barrier. | 254 // Update the write barrier. |
252 __ RecordWriteContextSlot( | 255 if (need_write_barrier) { |
253 cp, target.offset(), a0, a3, kRAHasBeenSaved, kDontSaveFPRegs); | 256 __ RecordWriteContextSlot( |
| 257 cp, target.offset(), a0, a3, kRAHasBeenSaved, kDontSaveFPRegs); |
| 258 } else if (FLAG_debug_code) { |
| 259 Label done; |
| 260 __ JumpIfInNewSpace(cp, a0, &done); |
| 261 __ Abort(kExpectedNewSpaceObject); |
| 262 __ bind(&done); |
| 263 } |
254 } | 264 } |
255 } | 265 } |
256 } | 266 } |
257 | 267 |
258 Variable* arguments = scope()->arguments(); | 268 Variable* arguments = scope()->arguments(); |
259 if (arguments != NULL) { | 269 if (arguments != NULL) { |
260 // Function uses arguments object. | 270 // Function uses arguments object. |
261 Comment cmnt(masm_, "[ Allocate arguments object"); | 271 Comment cmnt(masm_, "[ Allocate arguments object"); |
262 if (!function_in_register) { | 272 if (!function_in_register) { |
263 // Load this again, if it's used by the local context below. | 273 // Load this again, if it's used by the local context below. |
(...skipping 4588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4852 Assembler::target_address_at(pc_immediate_load_address)) == | 4862 Assembler::target_address_at(pc_immediate_load_address)) == |
4853 reinterpret_cast<uint32_t>( | 4863 reinterpret_cast<uint32_t>( |
4854 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4864 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4855 return OSR_AFTER_STACK_CHECK; | 4865 return OSR_AFTER_STACK_CHECK; |
4856 } | 4866 } |
4857 | 4867 |
4858 | 4868 |
4859 } } // namespace v8::internal | 4869 } } // namespace v8::internal |
4860 | 4870 |
4861 #endif // V8_TARGET_ARCH_MIPS | 4871 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |