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

Side by Side Diff: src/a64/lithium-codegen-a64.cc

Issue 141363005: A64: Synchronize with r15204. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 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/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.h » ('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 // 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 } 161 }
162 162
163 private: 163 private:
164 Condition cond_; 164 Condition cond_;
165 const Register& value_; 165 const Register& value_;
166 uint64_t mask_; 166 uint64_t mask_;
167 }; 167 };
168 168
169 169
170 void LCodeGen::WriteTranslation(LEnvironment* environment, 170 void LCodeGen::WriteTranslation(LEnvironment* environment,
171 Translation* translation, 171 Translation* translation) {
172 int* pushed_arguments_index,
173 int* pushed_arguments_count) {
174 if (environment == NULL) return; 172 if (environment == NULL) return;
175 173
176 // The translation includes one command per value in the environment. 174 // The translation includes one command per value in the environment.
177 int translation_size = environment->values()->length(); 175 int translation_size = environment->translation_size();
178 // The output frame height does not include the parameters. 176 // The output frame height does not include the parameters.
179 int height = translation_size - environment->parameter_count(); 177 int height = translation_size - environment->parameter_count();
180 178
181 // Function parameters are arguments to the outermost environment. The 179 WriteTranslation(environment->outer(), translation);
182 // arguments index points to the first element of a sequence of tagged
183 // values on the stack that represent the arguments. This needs to be
184 // kept in sync with the LArgumentsElements implementation.
185 *pushed_arguments_index = -environment->parameter_count();
186 *pushed_arguments_count = environment->parameter_count();
187
188 WriteTranslation(environment->outer(),
189 translation,
190 pushed_arguments_index,
191 pushed_arguments_count);
192 bool has_closure_id = !info()->closure().is_null() && 180 bool has_closure_id = !info()->closure().is_null() &&
193 !info()->closure().is_identical_to(environment->closure()); 181 !info()->closure().is_identical_to(environment->closure());
194 int closure_id = has_closure_id 182 int closure_id = has_closure_id
195 ? DefineDeoptimizationLiteral(environment->closure()) 183 ? DefineDeoptimizationLiteral(environment->closure())
196 : Translation::kSelfLiteralId; 184 : Translation::kSelfLiteralId;
197 185
198 switch (environment->frame_type()) { 186 switch (environment->frame_type()) {
199 case JS_FUNCTION: 187 case JS_FUNCTION:
200 translation->BeginJSFrame(environment->ast_id(), closure_id, height); 188 translation->BeginJSFrame(environment->ast_id(), closure_id, height);
201 break; 189 break;
(...skipping 13 matching lines...) Expand all
215 case STUB: 203 case STUB:
216 translation->BeginCompiledStubFrame(); 204 translation->BeginCompiledStubFrame();
217 break; 205 break;
218 case ARGUMENTS_ADAPTOR: 206 case ARGUMENTS_ADAPTOR:
219 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 207 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
220 break; 208 break;
221 default: 209 default:
222 UNREACHABLE(); 210 UNREACHABLE();
223 } 211 }
224 212
225 // Inlined frames which push their arguments cause the index to be
226 // bumped and another stack area to be used for materialization,
227 // otherwise actual argument values are unknown for inlined frames.
228 bool arguments_known = true;
229 int arguments_index = *pushed_arguments_index;
230 int arguments_count = *pushed_arguments_count;
231 if (environment->entry() != NULL) {
232 arguments_known = environment->entry()->arguments_pushed();
233 arguments_index = arguments_index < 0
234 ? GetStackSlotCount() : arguments_index + arguments_count;
235 arguments_count = environment->entry()->arguments_count() + 1;
236 if (environment->entry()->arguments_pushed()) {
237 *pushed_arguments_index = arguments_index;
238 *pushed_arguments_count = arguments_count;
239 }
240 }
241
242 for (int i = 0; i < translation_size; ++i) { 213 for (int i = 0; i < translation_size; ++i) {
243 LOperand* value = environment->values()->at(i); 214 LOperand* value = environment->values()->at(i);
244 // spilled_registers_ and spilled_double_registers_ are either 215 // spilled_registers_ and spilled_double_registers_ are either
245 // both NULL or both set. 216 // both NULL or both set.
246 if ((environment->spilled_registers() != NULL) && (value != NULL)) { 217 if ((environment->spilled_registers() != NULL) && (value != NULL)) {
247 if (value->IsRegister() && 218 if (value->IsRegister() &&
248 (environment->spilled_registers()[value->index()] != NULL)) { 219 (environment->spilled_registers()[value->index()] != NULL)) {
249 translation->MarkDuplicate(); 220 translation->MarkDuplicate();
250 AddToTranslation(translation, 221 AddToTranslation(translation,
251 environment->spilled_registers()[value->index()], 222 environment->spilled_registers()[value->index()],
252 environment->HasTaggedValueAt(i), 223 environment->HasTaggedValueAt(i),
253 environment->HasUint32ValueAt(i), 224 environment->HasUint32ValueAt(i));
254 arguments_known,
255 arguments_index,
256 arguments_count);
257 } else if ( 225 } else if (
258 value->IsDoubleRegister() && 226 value->IsDoubleRegister() &&
259 (environment->spilled_double_registers()[value->index()] != NULL)) { 227 (environment->spilled_double_registers()[value->index()] != NULL)) {
260 translation->MarkDuplicate(); 228 translation->MarkDuplicate();
261 AddToTranslation( 229 AddToTranslation(
262 translation, 230 translation,
263 environment->spilled_double_registers()[value->index()], 231 environment->spilled_double_registers()[value->index()],
264 false, 232 false,
265 false, 233 false);
266 arguments_known,
267 arguments_index,
268 arguments_count);
269 } 234 }
270 } 235 }
271 236
237 // TODO(mstarzinger): Introduce marker operands to indicate that this value
238 // is not present and must be reconstructed from the deoptimizer. Currently
239 // this is only used for the arguments object.
240 if (value == NULL) {
241 int arguments_count = environment->values()->length() - translation_size;
242 translation->BeginArgumentsObject(arguments_count);
243 for (int i = 0; i < arguments_count; ++i) {
244 LOperand* value = environment->values()->at(translation_size + i);
245 ASSERT(environment->spilled_registers() == NULL ||
246 !value->IsRegister() ||
247 environment->spilled_registers()[value->index()] == NULL);
248 ASSERT(environment->spilled_registers() == NULL ||
249 !value->IsDoubleRegister() ||
250 environment->spilled_double_registers()[value->index()] == NULL);
251 AddToTranslation(translation,
252 value,
253 environment->HasTaggedValueAt(translation_size + i),
254 environment->HasUint32ValueAt(translation_size + i));
255 }
256 continue;
257 }
258
272 AddToTranslation(translation, 259 AddToTranslation(translation,
273 value, 260 value,
274 environment->HasTaggedValueAt(i), 261 environment->HasTaggedValueAt(i),
275 environment->HasUint32ValueAt(i), 262 environment->HasUint32ValueAt(i));
276 arguments_known,
277 arguments_index,
278 arguments_count);
279 } 263 }
280 } 264 }
281 265
282 266
283 void LCodeGen::AddToTranslation(Translation* translation, 267 void LCodeGen::AddToTranslation(Translation* translation,
284 LOperand* op, 268 LOperand* op,
285 bool is_tagged, 269 bool is_tagged,
286 bool is_uint32, 270 bool is_uint32) {
287 bool arguments_known, 271 if (op->IsStackSlot()) {
288 int arguments_index,
289 int arguments_count) {
290 if (op == NULL) {
291 // TODO(twuerthinger): Introduce marker operands to indicate that this value
292 // is not present and must be reconstructed from the deoptimizer. Currently
293 // this is only used for the arguments object.
294 translation->StoreArgumentsObject(
295 arguments_known, arguments_index, arguments_count);
296 } else if (op->IsStackSlot()) {
297 if (is_tagged) { 272 if (is_tagged) {
298 translation->StoreStackSlot(op->index()); 273 translation->StoreStackSlot(op->index());
299 } else if (is_uint32) { 274 } else if (is_uint32) {
300 translation->StoreUint32StackSlot(op->index()); 275 translation->StoreUint32StackSlot(op->index());
301 } else { 276 } else {
302 translation->StoreInt32StackSlot(op->index()); 277 translation->StoreInt32StackSlot(op->index());
303 } 278 }
304 } else if (op->IsDoubleStackSlot()) { 279 } else if (op->IsDoubleStackSlot()) {
305 translation->StoreDoubleStackSlot(op->index()); 280 translation->StoreDoubleStackSlot(op->index());
306 } else if (op->IsArgument()) { 281 } else if (op->IsArgument()) {
(...skipping 30 matching lines...) Expand all
337 deoptimization_literals_.Add(literal, zone()); 312 deoptimization_literals_.Add(literal, zone());
338 return result; 313 return result;
339 } 314 }
340 315
341 316
342 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, 317 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
343 Safepoint::DeoptMode mode) { 318 Safepoint::DeoptMode mode) {
344 if (!environment->HasBeenRegistered()) { 319 if (!environment->HasBeenRegistered()) {
345 int frame_count = 0; 320 int frame_count = 0;
346 int jsframe_count = 0; 321 int jsframe_count = 0;
347 int args_index = 0;
348 int args_count = 0;
349 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 322 for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
350 ++frame_count; 323 ++frame_count;
351 if (e->frame_type() == JS_FUNCTION) { 324 if (e->frame_type() == JS_FUNCTION) {
352 ++jsframe_count; 325 ++jsframe_count;
353 } 326 }
354 } 327 }
355 Translation translation(&translations_, frame_count, jsframe_count, zone()); 328 Translation translation(&translations_, frame_count, jsframe_count, zone());
356 WriteTranslation(environment, &translation, &args_index, &args_count); 329 WriteTranslation(environment, &translation);
357 int deoptimization_index = deoptimizations_.length(); 330 int deoptimization_index = deoptimizations_.length();
358 int pc_offset = masm()->pc_offset(); 331 int pc_offset = masm()->pc_offset();
359 environment->Register(deoptimization_index, 332 environment->Register(deoptimization_index,
360 translation.index(), 333 translation.index(),
361 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 334 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
362 deoptimizations_.Add(environment, zone()); 335 deoptimizations_.Add(environment, zone());
363 } 336 }
364 } 337 }
365 338
366 339
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 __ Mov(x2, Operand(instr->hydrogen()->property_cell())); 404 __ Mov(x2, Operand(instr->hydrogen()->property_cell()));
432 405
433 ElementsKind kind = instr->hydrogen()->elements_kind(); 406 ElementsKind kind = instr->hydrogen()->elements_kind();
434 bool disable_allocation_sites = 407 bool disable_allocation_sites =
435 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE); 408 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE);
436 409
437 if (instr->arity() == 0) { 410 if (instr->arity() == 0) {
438 ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites); 411 ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites);
439 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 412 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
440 } else if (instr->arity() == 1) { 413 } else if (instr->arity() == 1) {
414 Label done;
415 if (IsFastPackedElementsKind(kind)) {
416 Label packed_case;
417
418 // We might need to create a holey array; look at the first argument.
419 __ Peek(x10, 0);
420 __ Cbz(x10, &packed_case);
421
422 ElementsKind holey_kind = GetHoleyElementsKind(kind);
423 ArraySingleArgumentConstructorStub stub(holey_kind,
424 disable_allocation_sites);
425 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
426 __ B(&done);
427 __ Bind(&packed_case);
428 }
429
441 ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites); 430 ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites);
442 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 431 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
432 __ Bind(&done);
443 } else { 433 } else {
444 ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites); 434 ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites);
445 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 435 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
446 } 436 }
447 437
448 ASSERT(ToRegister(instr->result()).is(x0)); 438 ASSERT(ToRegister(instr->result()).is(x0));
449 } 439 }
450 440
451 441
452 void LCodeGen::CallRuntime(const Runtime::Function* function, 442 void LCodeGen::CallRuntime(const Runtime::Function* function,
(...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after
2199 } 2189 }
2200 } 2190 }
2201 2191
2202 2192
2203 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { 2193 void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
2204 Register reg = ToRegister(instr->value()); 2194 Register reg = ToRegister(instr->value());
2205 Handle<JSFunction> target = instr->hydrogen()->target(); 2195 Handle<JSFunction> target = instr->hydrogen()->target();
2206 AllowDeferredHandleDereference smi_check; 2196 AllowDeferredHandleDereference smi_check;
2207 if (isolate()->heap()->InNewSpace(*target)) { 2197 if (isolate()->heap()->InNewSpace(*target)) {
2208 Register temp = ToRegister(instr->temp()); 2198 Register temp = ToRegister(instr->temp());
2209 Handle<JSGlobalPropertyCell> cell = 2199 Handle<Cell> cell = isolate()->factory()->NewPropertyCell(target);
2210 isolate()->factory()->NewJSGlobalPropertyCell(target);
2211 __ Mov(temp, Operand(Handle<Object>(cell))); 2200 __ Mov(temp, Operand(Handle<Object>(cell)));
2212 __ Ldr(temp, FieldMemOperand(temp, JSGlobalPropertyCell::kValueOffset)); 2201 __ Ldr(temp, FieldMemOperand(temp, Cell::kValueOffset));
2213 __ Cmp(reg, temp); 2202 __ Cmp(reg, temp);
2214 } else { 2203 } else {
2215 __ Cmp(reg, Operand(target)); 2204 __ Cmp(reg, Operand(target));
2216 } 2205 }
2217 DeoptimizeIf(ne, instr->environment()); 2206 DeoptimizeIf(ne, instr->environment());
2218 } 2207 }
2219 2208
2220 2209
2221 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { 2210 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
2222 EnsureSpaceForLazyDeopt(); 2211 EnsureSpaceForLazyDeopt();
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
3024 Deoptimize(instr->environment()); 3013 Deoptimize(instr->environment());
3025 3014
3026 // All done. 3015 // All done.
3027 __ Bind(&done); 3016 __ Bind(&done);
3028 } 3017 }
3029 3018
3030 3019
3031 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 3020 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
3032 Register result = ToRegister(instr->result()); 3021 Register result = ToRegister(instr->result());
3033 __ Mov(result, Operand(Handle<Object>(instr->hydrogen()->cell()))); 3022 __ Mov(result, Operand(Handle<Object>(instr->hydrogen()->cell())));
3034 __ Ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset)); 3023 __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset));
3035 if (instr->hydrogen()->RequiresHoleCheck()) { 3024 if (instr->hydrogen()->RequiresHoleCheck()) {
3036 DeoptimizeIfRoot( 3025 DeoptimizeIfRoot(
3037 result, Heap::kTheHoleValueRootIndex, instr->environment()); 3026 result, Heap::kTheHoleValueRootIndex, instr->environment());
3038 } 3027 }
3039 } 3028 }
3040 3029
3041 3030
3042 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 3031 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
3043 ASSERT(ToRegister(instr->global_object()).Is(x0)); 3032 ASSERT(ToRegister(instr->global_object()).Is(x0));
3044 ASSERT(ToRegister(instr->result()).Is(x0)); 3033 ASSERT(ToRegister(instr->result()).Is(x0));
(...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after
4452 4441
4453 // Load the cell. 4442 // Load the cell.
4454 __ Mov(cell, Operand(instr->hydrogen()->cell())); 4443 __ Mov(cell, Operand(instr->hydrogen()->cell()));
4455 4444
4456 // If the cell we are storing to contains the hole it could have 4445 // If the cell we are storing to contains the hole it could have
4457 // been deleted from the property dictionary. In that case, we need 4446 // been deleted from the property dictionary. In that case, we need
4458 // to update the property details in the property dictionary to mark 4447 // to update the property details in the property dictionary to mark
4459 // it as no longer deleted. We deoptimize in that case. 4448 // it as no longer deleted. We deoptimize in that case.
4460 if (instr->hydrogen()->RequiresHoleCheck()) { 4449 if (instr->hydrogen()->RequiresHoleCheck()) {
4461 Register payload = ToRegister(instr->temp2()); 4450 Register payload = ToRegister(instr->temp2());
4462 __ Ldr(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 4451 __ Ldr(payload, FieldMemOperand(cell, Cell::kValueOffset));
4463 DeoptimizeIfRoot( 4452 DeoptimizeIfRoot(
4464 payload, Heap::kTheHoleValueRootIndex, instr->environment()); 4453 payload, Heap::kTheHoleValueRootIndex, instr->environment());
4465 } 4454 }
4466 4455
4467 // Store the value. 4456 // Store the value.
4468 __ Str(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 4457 __ Str(value, FieldMemOperand(cell, Cell::kValueOffset));
4469 // Cells are always rescanned, so no write barrier here. 4458 // Cells are always rescanned, so no write barrier here.
4470 } 4459 }
4471 4460
4472 4461
4473 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { 4462 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
4474 ASSERT(ToRegister(instr->global_object()).Is(x1)); 4463 ASSERT(ToRegister(instr->global_object()).Is(x1));
4475 ASSERT(ToRegister(instr->value()).Is(x0)); 4464 ASSERT(ToRegister(instr->value()).Is(x0));
4476 4465
4477 __ Mov(x2, Operand(instr->name())); 4466 __ Mov(x2, Operand(instr->name()));
4478 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4467 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
5282 __ Bind(&out_of_object); 5271 __ Bind(&out_of_object);
5283 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 5272 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
5284 // Index is equal to negated out of object property index plus 1. 5273 // Index is equal to negated out of object property index plus 1.
5285 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 5274 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2));
5286 __ Ldr(result, FieldMemOperand(result, 5275 __ Ldr(result, FieldMemOperand(result,
5287 FixedArray::kHeaderSize - kPointerSize)); 5276 FixedArray::kHeaderSize - kPointerSize));
5288 __ Bind(&done); 5277 __ Bind(&done);
5289 } 5278 }
5290 5279
5291 } } // namespace v8::internal 5280 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698